Не может использовать сообщение ActiveMQ на tomcat
Я пытаюсь настроить Apache Active MQ в Apache Tomcat. У меня есть два файла war, MessageProducer.war и MessageConsumer.war. Я добавил все банки зависимостей ActiveMQ в папку /WebContent/WEB-INF/lib обоих проектов. Я добавил следующие ресурсы, настроенные в файлах context.xml обеих войн. И файл context.xml помещается в папку /WebContent/META-INF/ для обеих войн.
context.xml
<Context>
<Resource
name="myConFactory"
auth="Container"
type="org.apache.activemq.ActiveMQConnectionFactory"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="vm://localhost"
brokerName="LocalActiveMQBroker"
useEmbeddedBroker="true"/>
<Resource name="jms/myTopic"
auth="Container"
type="org.apache.activemq.command.ActiveMQTopic"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="com.myproject.TOPIC"/>
</Context>
Записи, связанные с ActiveMQ, настраиваются в файле web.xml, как показано ниже для обеих войн.
web.xml
<resource-env-ref>
<resource-env-ref-name>myConFactory</resource-env-ref-name>
<resource-env-ref-type>org.apache.activemq.ActiveMQConnectionFactory</resource-env-ref-type>
</resource-env-ref>
<resource-env-ref>
<resource-env-ref-name>jms/myTopic</resource-env-ref-name>
<resource-env-ref-type>org.apache.activemq.command.ActiveMQTopic</resource-env-ref-type>
</resource-env-ref>
Файл MessageProducer.java в MessageProducer.war, будет публиковать сообщения в теме. Ниже приведен код для того же:
try {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.put(Context.PROVIDER_URL,"vm://localhost");
Context context = new InitialContext(props);
TopicConnectionFactory factory = (TopicConnectionFactory)
context.lookup("java:comp/env/myConFactory");
TopicConnection connection = factory.createTopicConnection();
session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) context.lookup("java:comp/env/jms/myTopic");
publisher = session.createPublisher(topic);
TextMessage tm = session.createTextMessage();
tm.setText("Sending Message with ActiveMQ");
publisher.publish(tm);
}
catch(Exceptione e) {
e.printStackTrace();
}
Я развернул MessageProducer.war на Tomcat v7.
Файл MessageConsumer.java находится в MessageConsumer.war, будет использовать сообщения, опубликованные MessageProducer. Ниже приведен код для того же:
public class MessageConsumer extends HttpServlet {
public TopicSession session = null;
public TopicConnection connection = null;
Topic topic = null;
TopicSubscriber subscriber = null;
public void init() {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.put(Context.PROVIDER_URL, "vm://localhost");
Context context = null;
try {
context = new InitialContext(props);
TopicConnectionFactory factory = null;
factory = (TopicConnectionFactory) context.
lookup("java:comp/env/myConFactory");
connection = factory.createTopicConnection();
connection.setClientID("DURABLE_SUBSCRIBER_ID");
session = connection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = (Topic) context.lookup("java:comp/env/jms/myTopic");
subscriber = session.createDurableSubscriber(topic,
"DURABLE_SUBSCRIBER");
connection.start();
TextMessage tm = (TextMessage) subscriber.receive(3000);
String strMsgRecieved = tm.getText();
} catch (NamingException | JMSException e) {
e.printStackTrace();
}
}
}
Я настроил класс MessageConsumer для запуска при запуске в web.xml, как показано ниже.
<servlet>
<servlet-name>startupServelt</servlet-name>
<servlet-class>com.myproject.MessageConsumer</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
Я развернул MessageConsumer.war на Tomcat v8. Tomcat v7 и v8 работают на одной физической машине и на одной и той же JVM. Когда я запускаю MessageProducer.war, он публикует сообщения в теме, которые я вижу через JConsole. Но когда я начну войну MessageConsumer, она покажет Запуск Apache Tomcat на 100% в течение бесконечного времени. Это не будет продолжаться. Он не будет отображать какие-либо исключения или что-либо на консоли Tomcat. И он не будет использовать опубликованное сообщение. Пожалуйста, дайте мне знать, что я делаю неправильно или почему это не работает.
2 ответа
Tomcat v7 и v8 работают на одной физической машине и на одной и той же JVM.
Я не уверен, как два экземпляра Tomcat могут работать на одной и той же JVM. Да, они могут использовать один и тот же JDK, и они могут работать на той же физической машине, но они не будут на той же JVM. Они оба запустят свою собственную JVM, независимую друг от друга.
В вашем случае вы используете встроенный брокер ActiveMQ, который, согласно документации, позволяет "клиентам соединяться друг с другом внутри виртуальной машины". В твоем случае, я думаю, это не та же ВМ. Потребитель сообщения, который ищет сообщение, смотрит на экземпляр ActiveMQ, отличный от того, на который производитель сообщения отправляет сообщение.
Это нормально для загрузки при запуске.
ваш startupServelt
при запуске будет прослушивать только одно сообщение, вам нужно перебрать subscriber.receive(3000);
в другой теме или использовать MessageListener
,
У вас есть любые другие журналы запуска Tomcat или ActiveMQ.
Вы говорите: для обоих Tomcats я настроил JRE8 для использования по умолчанию. Так что оба используют одну и ту же JVM! Таким образом, оба используют одну и ту же версию JVM, но не одну и ту же работающую JVM. я думаю, что здесь проблема, MessageConsumer.war работает на Tomcat v8 и использует сообщения от AMQ на v8 и MessageProducer.war на Tomcat v7 и отправляет сообщения на AMQ на v7. по этой причине все в порядке, вы можете видеть, что производитель создает сообщения, но потребитель ничего не получает, так как он находится в другой JVM, чем производитель, и нет производителя, который мог бы отправлять сообщения своему брокеру!!
вам нужно развернуть 2 приложения на одном и том же Tomcat, чтобы он работал.