Activemq如何配置使用者监听器(用Java)

时间:2012-01-28 21:51:40

标签: java activemq producer-consumer

如果有人在Spring中分享基于xml的消费者监听器配置的简单示例,我会很高兴。提前谢谢。

修改;

我只是想听听消费者的听众,而不是消费者的实现,因为我已经在我的应用中实现了一个active-mq。并且它运行良好,但我无法确定生产者同步发送的消费项目的顺序。 问题是由于同时执行一个方法(将某些对象持久化到db以便记录它们)而导致的不一致和数据操作。

EDIT2: 让我澄清这种复杂性。我有一个由两个基本独立部分组成的应用程序。第一个是同步执行的生产者,它向db询问新产品,然后“逐个”通过active-mq提供的“jmsTemplate.send”方法发送它们。这是从Cron / Timer同步执行的操作。换句话说,生产者正在从计时器/ cron执行。现在问题是消费者本身。当生产者“逐个”发送产品时,异步消费者(启用并发)接收产品并异步使用它们。

问题从这里开始。因为在刚刚收到产品时从使用者执行的方法会执行一些数据库持久性操作。当相同的产品被单独的并发消费者接收时(它发生在我们的系统,而不是jms问题,不要注意这一点),然后对同一实体执行相同的持久性操作会发生一些容易预测的异常。如何防止产品的异步操作或管理此类应用程序中的消费产品订单。

感谢。

1 个答案:

答案 0 :(得分:7)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jms="http://www.springframework.org/schema/jms"
   xmlns:p="http://www.springframework.org/schema/p"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                       http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">

<!-- A simple and usual connection to activeMQ -->  
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616"></property>
</bean>                

 <!-- A POJO that implements the JMS message listener -->
<bean id="simpleMessageListener" class="MyJMSMessageListener" />


<!-- Cached Connection Factory to wrap the ActiveMQ connetion -->
<bean id="cachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">     
    <property name="targetConnectionFactory" ref="activeMQConnectionFactory"></property>
    <property name="sessionCacheSize" value="10"></property>
    <property name="reconnectOnException" value="true"></property>
</bean>


<!-- The Spring message listener container configuration -->
<jms:listener-container container-type="default" connection-factory="cachedConnectionFactory" acknowledge="auto">
    <jms:listener destination="FOO.TEST" ref="simpleMessageListener" method="onMessage" />
</jms:listener-container>

</beans>

侦听消息的Java类:

import javax.jms.Message;
import javax.jms.MessageListener;
public class MyJMSMessageListener implements MessageListener{

    @Override
    public void onMessage(Message message) {
    // Do your work here
    }

}

启动此侦听器需要获取应用程序上下文,它会在您执行此操作后自动启动JMS侦听器。

根据其他问题编辑

因此,您的系统可能会生成(例如)使用相同productID传递给消费者的2条甚至更多消息?首先,这不是你的问题,而是应用程序的问题。即使你以某种方式修复它,它也不是真正的修复,但它是一种隐藏问题本身的方法。尽管如此,如果现在被迫提供解决方案,我只能想到一个,最简单的,禁用并发消费,等等。这是我要做的:接收队列中的消息,并在该队列上只有一个消费者。在这个Consumer中,我会尽可能少地处理消息 - 只接受productID并将其放在其他队列中。在此之前,您必须始终检查productID是否已在该队列中。如果它只是静默返回,如果不是,则意味着它从未被处理过,因此将此消息放在另一个Queue:Queue2中,然后在第二个Queue Queue2上启用并发使用者。这仍然有缺陷:首先,productID队列应该以某种方式偶尔清理一次,否则它将永远增长,但那就是那么难。棘手的部分:如果你在productID队列中有一个productID,但是产品是在DB中进行UPDATE而不是INSERT会怎么样?你不应该拒绝它......