`
Riddick
  • 浏览: 642178 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

用ActiveMQ遇到的消息确认问题

阅读更多
问题:我的ActiveMQ接收消息用的是topic模式,持久化订阅,问题是我用了JMS接收消息的代码每次重新启动总是会收到最后一次的消息,但这些消息是已经接收过了的,而且启动一次就收到一次,难道ActiveMQ不会清除缓存的吗?
//创建JMS连接和会话
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);   
connection = factory.createConnection();   
connection.setClientID(Constant.JMS_CLIENT_ID);   
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
// 创建消息发送主题和发送者
Topic jmsSendTopic = session.createTopic(sendTopic);
sendTopicProducer = session.createProducer(jmsSendTopic);
sendTopicProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
sendTopicProducer.setTimeToLive(Message.DEFAULT_TIME_TO_LIVE);
// 创建消息接收主题和接收者
Topic jmsReceiveTopic = session.createTopic(receiveTopic);
receiveTopicConsumer = session.createDurableSubscriber(jmsReceiveTopic,Constant.JMS_SUBSCRIBE_NAME);
receiveTopicConsumer.setMessageListener(this);
connection.start();  

解答:问题原因在于这段代码在接收到JMS消息时不会向ActiveMQ服务器确认消息的接收,故而ActiveMQ服务器一直认为该消息没有成功发送给接收者,因而每次接收者重启之后就会收到ActiveMQ服务器发送过来的消息。在这里要解释一下session的创建。
session = connection.createSession(true,Session.Auto_ACKNOWLEDGE);

当createSession第一个参数为true时,表示创建的session被标记为transactional的,确认消息就通过确认和校正来自动地处理,第二个参数应该是没用的。
session = connection.createSession(false,Session.Auto_ACKNOWLEDGE);

当createSession的第一个参数为false时,表示创建的session没有标记为transactional,此时有三种用于消息确认的选项:
**AUTO_ACKNOWLEDGE session将自动地确认收到的一则消息;
**CLIENT_ACKNOWLEDGE 客户端程序将确认收到的一则消息,调用这则消息的确认方法;
**DUPS_OK_ACKNOWLEDGE 这个选项命令session“懒散的”确认消息传递,可以想到,这将导致消息提供者传递的一些复制消息可能出错。

JMS有两种消息传递方式。标记为NON_PERSISTENT的消息最多传递一次,而标记为PERSISTENT的消息将使用暂存后再转发的机理投递。如果一个JMS服务离线,那么持久性消息不会丢失,但是得等到这个服务恢复联机的时候才会被传递。所以默认的消息传递方式是非持久性的,虽然使用非持久性消息可能降低内存和需要的存储器,但这种传递方式只有当你不需要接收所有消息时才使用。
因此正确的代码只需改动一处就行了,即将true改为false
//创建JMS连接和会话
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);   
connection = factory.createConnection();   
connection.setClientID(Constant.JMS_CLIENT_ID);   
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建消息发送主题和发送者
Topic jmsSendTopic = session.createTopic(sendTopic);
sendTopicProducer = session.createProducer(jmsSendTopic);
sendTopicProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
sendTopicProducer.setTimeToLive(Message.DEFAULT_TIME_TO_LIVE);
// 创建消息接收主题和接收者
Topic jmsReceiveTopic = session.createTopic(receiveTopic);
receiveTopicConsumer = session.createDurableSubscriber(jmsReceiveTopic,Constant.JMS_SUBSCRIBE_NAME);
receiveTopicConsumer.setMessageListener(this);
connection.start();  



分享到:
评论
1 楼 liumuqi110 2012-12-21  
你的结论是错误的吧。。这是因为事务问题。你没提交  这个就会滚 从发你了

相关推荐

    activeMQ发送消息返回消息

    10. **异常处理**:在发送和接收消息过程中,可能遇到网络问题、服务器故障等情况。ActiveMQ提供了重试和死信队列等机制来处理这些问题,确保消息的可靠传递。 在实际应用中,ActiveMQ的配置和使用可能更复杂,需要...

    7道消息队列ActiveMQ面试题!

    ActiveMQ是一款非常流行的开源消息队列中间件,它实现了JMS...了解和掌握这些知识点,有助于面试者在面试中展示对ActiveMQ的深入理解和实际应用能力,同时也是确保在日常开发工作中正确、高效使用消息队列的重要基础。

    ActiveMQ问题解决记录

    通过使用消息队列,ActiveMQ可以确保即使在高负载或网络故障的情况下,数据也能可靠地传递,提高了系统的可伸缩性和稳定性。 在源码层面,ActiveMQ的设计基于Apache Apollo项目,它的架构包括Broker(消息代理)、...

    ActiveMQ消息中间件面试题.pdf

    在某些场景下,可能遇到多个消费者之间消息分发不均衡的问题,即一个消费者处理了大部分甚至全部消息,而其他消费者几乎没有参与处理。这主要是由于ActiveMQ的预取(Prefetch)机制导致的: - 默认情况下,消费者一...

    ActiveMQ消息中间件面试专题.pdf

    为了避免这种问题,推荐使用持久化消息或及时处理非持久化消息,不使其堆积。此外,开启事务模式可以确保消息的可靠传递,因为commit()方法会等待服务器返回确认,从而避免了因超时导致的消息丢失。 持久化消息的...

    7道消息队列ActiveMQ面试题!.zip

    手动确认则需要消费者显式发送确认,这样在处理过程中遇到问题时,消息可以被重新投递。 理解并掌握这些ActiveMQ的核心概念和特性,对于开发者来说至关重要,特别是当设计和实现需要高并发、高可靠性的系统时。通过...

    apache-activemq-5.15.2-bin.zip

    9. **改进与修复**:ActiveMQ 5.15.2版特别强调了问题的解决和错误修复,这意味着在使用此版本时,用户将遇到较少的已知问题,系统的稳定性和可靠性得到了显著提升。 10. **社区支持**:作为Apache项目的一部分,...

    ActiveMQ-CPP在vs2017上测试通过

    ActiveMQ-CPP是Apache ActiveMQ的C++客户端库,它允许开发者在C++应用程序中使用消息中间件的功能,实现高效的异步通信。在本文中,我们将深入探讨如何在Visual Studio 2017(简称VS2017)环境下成功配置和测试...

    JMS ActiveMQ

    在实际应用中,可能遇到的问题包括消息丢失、性能优化、高并发处理、安全策略等。针对这些问题,开发者需要了解ActiveMQ的配置选项,进行适当的调整以满足具体需求。 总结:JMS ActiveMQ结合了JMS规范和ActiveMQ的...

    ( apache-activemq-5.13.0-bin.zip )

    当遇到问题时,可以查看日志文件(通常在`data/`目录下)进行诊断,同时ActiveMQ提供了一些监控指标,帮助识别和解决性能瓶颈。 综上所述,`( apache-activemq-5.13.0-bin.zip )`是一个包含Apache ActiveMQ 5.13.0...

    ActiveMQ面试专题.docx

    如果消息已自动确认,可以通过使用`consumer.receive()`方法而不是`consumer.getMessageListener()`来消费消息,这样可以在确认消息前进行处理或重试。 除此之外,还有其他一些面试中可能讨论的话题,如ActiveMQ的...

    apache-activemq-5.15.11-bin.zip

    Apache ActiveMQ是业界广泛使用的开源消息代理和队列服务器,它是Apache软件基金会的一部分,属于Java消息服务(JMS)提供商。...在使用过程中,遇到问题时,官方文档和社区资源都能提供宝贵的帮助。

    结合Spring2.0和ActiveMQ进行异步消息调用

    在实际开发中,我们可能会遇到一些问题,如消息的持久化、事务支持以及消息确认策略等。ActiveMQ提供了多种选项来确保消息的可靠传输,例如使用Durable Subscription可以保证即使消费者不在线,消息也不会丢失。同时...

    BlazeDS+Spring+activeMQ outofmemory

    7. **使用消息确认**:在ActiveMQ中启用消息确认,确保消息被正确消费并从队列中移除。 综上所述,解决这个问题需要对BlazeDS、Spring和ActiveMQ的集成有深入理解,同时也需要熟悉Java和ActionScript的内存管理。...

    使用jms 操作ActiveMQ

    实践中,你可能会遇到配置ActiveMQ服务器、处理消息确认、事务管理、消息持久化等更高级的话题,这些都是JMS和ActiveMQ在实际应用中的重要组成部分。 总之,掌握JMS与ActiveMQ的结合使用,能帮助你构建高效、健壮的...

    ActiveMQ实例

    在本实例中,我们将探讨如何下载、安装和使用ActiveMQ,以及创建基本的发送和接收消息的Java应用程序。 1. **下载与安装ActiveMQ** 要开始使用ActiveMQ,首先需要访问其官方网站(http://activemq.apache.org/)...

    linux activemq-cpp-library-3.8.2-src.tar.gz

    在使用过程中,可能会遇到网络问题、权限问题或者配置错误等。通过检查日志输出、设置调试级别以及使用try-catch语句捕获异常,可以帮助定位并解决问题。 总结,ActiveMQ-CPP库为Linux(Debian)系统上的C++开发者...

    ActiveMQ in Action

    总的来说,《ActiveMQ in Action》这本书不仅介绍了ActiveMQ的基础概念和用法,还涵盖了实际开发和部署中可能遇到的各种问题,是学习和掌握ActiveMQ不可或缺的参考书籍。通过阅读和实践书中的例子,开发者可以更好地...

    ActiveMQ集群

    这有助于确保消息能够被正确地传递到目标消费者,即使消息在传输过程中遇到了故障节点。 - **实现**: 在ActiveMQ中,可以通过设置`networkConnector`来实现存储转发机制,如上文所示的例子。 #### 四、总结 综上所...

    ActiveMQ JDBC集群总结

    ### ActiveMQ JDBC 集群总结 #### 一、ActiveMQ版本及环境信息 - **ActiveMQ 版本**:5.9.0 ...需要注意的是,在实际部署过程中可能还会遇到各种问题,比如网络配置、权限管理等,都需要根据实际情况进行调整。

Global site tag (gtag.js) - Google Analytics