我有兩個Java獨立應用程序。我想從一個應用程序發送消息,並通過兩個客戶端異步接收消息:一個與發送者位於同一個應用程序中。另一個是在不同的應用程序。兩者都與ActiveMQ代理連接。但我只能看到第一個客戶端收到了消息,而另一個客戶卻沒有收到消息。通過JMS連接兩個應用程序的一般方法是什麼?我想我必須對JMS有一些不清楚的概念。我查了一下,但無法弄清楚如何設置我的Spring bean配置文件來在兩個Java應用程序之間發佈/訂閱消息。如何在兩個應用程序之間發佈/訂閱JMS消息?
這裏是第一個應用程序我的發件人的bean配置文件,也是第一個聽衆的豆這是在同一個應用程序:
<bean id="customerMessageSender" class="com.example.message.CustomerStatusSender">
<property name="jmsTemplate" ref="jsmTemplateBean" />
<property name="topic" ref="topicBean" />
</bean>
<bean id="jsmTemplateBean" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactoryBean"/>
<property name="pubSubDomain" value="true"/>
</bean>
<bean id="topicBean" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="CustomerStatusTopic" />
</bean>
<bean id="connectionFactoryBean" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="customerStatusListener" class="com.example.message.CustomerStatusListener" />
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactoryBean" />
<property name="destination" ref="topicBean" />
<property name="messageListener" ref="customerStatusListener" />
</bean>
下面是第二個偵聽器bean的配置文件,該文件是在不同的應用:
<bean id="topicBean" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="CustomerStatusTopic" />
</bean>
<bean id="connectionFactoryBean" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="anotherCustomerStatusListener" class="com.mydomain.jms.CustomerStatusMessageListener" />
<bean id="listenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactoryBean" />
<property name="destination" ref="topicBean" />
<property name="messageListener" ref="anotherCustomerStatusListener" />
</bean>
正如你所看到的,customerStatusListener
豆和anotherCustomerStatusListener
豆訂閱topicBean
。但是,只有第一個偵聽器才能獲取該郵件,因爲它與發件人位於同一個應用程序中,而第二個偵聽器則沒有。通過JMS連接兩個Java應用程序的一般原則是什麼?這樣可以在兩個獨立的應用程序之間發送/接收消息?
編輯:由於類CustomerStatusMessageListener
在不同的應用程序中,所以在第一個XML文件中無法添加以下監聽器Bean,因此在第一個(發件人)應用程序的類路徑中不可見。
<bean id="anotherCustomerStatusListener" class="com.mydomain.jms.CustomerStatusMessageListener" />
再次編輯:以下是在第二應用程序,它是從第一應用單獨的第二監聽器。它包含一個main
方法來實例化偵聽器bean(jms-beans.xml是上面列出的第二個偵聽器的bean配置文件)。
public class CustomerStatusMessageListener implements MessageListener {
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
System.out.println("Subscriber 2 got you! The message is: "
+ ((TextMessage) message).getText());
} catch (JMSException ex) {
throw new RuntimeException(ex);
}
} else {
throw new IllegalArgumentException(
"Message must be of type TextMessage");
}
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("jms-beans.xml");
CustomerStatusMessageListener messageListener = (CustomerStatusMessageListener) context.getBean("anotherCustomerStatusListener");
context.close();
}
}
感謝您的建議。對於您指出的第一個項目,兩個偵聽器都運行在相同的主機和相同的JVM上。對於第二個項目,當第一個應用程序發送消息時,第二個偵聽器沒有運行,即當第一個應用程序將消息發送到ActiveMQ主題時,第二個應用程序未處於活動狀態。那麼如何讓第二個偵聽器在啓動後檢索消息呢?我最初的想法是:JMS允許任何消息監聽器即使在離線一段時間後也能獲得消息。真的嗎? – tonga
另外我運行這兩個應用程序的方式是:我在這兩個應用程序中有兩個'static main()'方法。我跑了第一個'main()',看到第一個聽衆得到了消息。然後我運行第二個'main()',但第二個監聽器沒有收到消息。我應該將這兩個應用程序放在同一個Web服務器上,並讓服務器作爲消息發送/接收的觸發點,而不是使用兩個'main()'方法作爲獨立的Java應用程序運行這兩個應用程序? – tonga
聽起來像你需要耐用的話題。我已經更新了有關在ActiveMQ中設置持久主題的信息。無論您決定將代碼作爲獨立的Java應用程序還是在服務器中運行,只要任一解決方案沒有延長的停機時間,就與JMS容器無關。你應該讓系統的其他需求驅動這部分體系結構。 – lreeder