一、序言
JMS 用于系统解耦有一定帮助,像我们 iteye 的一些系统消息,可能非重要要消息,就没那么严格的限制,统一异步发送就行了,反正上线你就能看到。有些情况下我们需要消息两端进行确认,比如一些比较重要的金额之类的信息。
二、实例场景
我们ERP系统中的财务模块是分开的,当成一个单独的财务系统,那么从ERP那么那送的财务信息,或者财务系统接收了,需要给ERP 那边一个确认信息,不然消息没处理成功或者其他异常,导致金额数据出问题,这个麻烦比较大的。
三、JMS 场景对应
场景一:
1.Producer -----> 发送消息到broker
2.Customer------> 从broker 收到消息
3.Customer------> 向broker 确认消息收到
对于场景一,可能没有完全满足我么你的实例场景,但是可以通过broker 获得,也算是一种异步通知,下面来看看对应的伪代码:
场景1.1 :开启事务的情况,是根据session 的commit 和 rollback 进行处理确认消息
// 这是我们消息生产者伪代码,初始化过程这里暂时不贴了,参考前面的 // true : 表示开启事务,开启事务,必须的commit Session session = InitJms.connection.createSession(true,Session.AUTO_ACKNOWLEDGE); // 创建一个文本消息 TextMessage message = session.createTextMessage("测试消息"); // 创建发送消息目的地 Destination send_destination = session.createQueue("order_queue"); // 生产者 MessageProducer producer = session.createProducer(send_destination); // 发送 producer.send(message); // 这里必须提交,因为开启了事务,不然broker 里面是看不到消息的 session.commit();
// 这是消费者代码,同样用true Session session = InitJms.connection.createSession(true,Session.CLIENT_ACKNOWLEDGE); // 指定接收消息的地方 Destination destination = session.createQueue("order_queue"); // 创建消费者 MessageConsumer consumer = session.createConsumer(destination); try { // 接收消息 TextMessage message = (TextMessage)consumer.receive(1000); System.out.println(message.getText()); // 收到消息之后进行确认 session.commit(); }finally { session.close(); InitJms.connection.close(); }
注意,上面由于没用messageListener 而且关闭了连接,因此控制台看不到消费者存在了:
场景1.2 我们自动响应服务器 和 非事务,客户端响应服务器的情况
// 消费端 在这里默认 采用AUTO 就会自动响应了 Session session = InitJms.connection.createSession(false,Session.AUTO_ACKNOWLEDGE); // 同理,如果设置 InitJms.connection.createSession(false,Session.CLIENT_ACKNOWLEDGE); // 就需要手动响应 message.acknowledge();
注意:如果没有按要求响应broker,消费端还是能拿到消息的,而且能重复拿到,5.11的版本可以拿到7次,可以通过下面的检查一些信息:
// 是否收到过消息,第一次fasle,第二次开始就是true message.getJMSRedelivered(); // 消息发送时间:毫秒 message.getJMSTimestamp(); // 从broker 重复获取消息的次数,5.11最多6次。 // 参考 RedeliveryPolicy DEFAULT_MAXIMUM_REDELIVERIES 可以更改 message.getStringProperty("JMSXDeliveryCount") // 消息存活时间:0 一直存在 message.getJMSExpiration(); 当然还有很多,可以参考官方文档: http://activemq.apache.org/activemq-message-properties.html 以及 http://activemq.apache.org/features.html
四、双向应答的场景:
双向应答可以这样描述
1.producer-->发送消息到broker, 然后等待确认消息
2.customer-->从broker 获得消息,然后发送确认消息--->broker
3.producer --> 从broker 获得确认消息
举个栗子:张三写封信送到邮局中转站,然后李四从中转站获得信,然后在写一份回执信,放到中转站,然后张三去取,当然张三写信的时候就得写明回信地址,看代码
// 承接刚才的代码,发送消息的时候,需要填写一个回执的地址 Destination recall_destination = session.createQueue("recall_queue"); // 将回执地址写在消息里面,方便李四知道 message.setJMSReplyTo(recall_destination); producer.send(message); // 发送之后,某个地方这里变成消息消费者,等待那边给我发送确认消息 MessageConsumer replyConsumer =session.createConsumer(recall_destination); // 这里我们用个消息监听 replyConsumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println(textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } });
消费者:
// 获得回执地址 Destination recall_destination = message.getJMSReplyTo(); // 创建回执消息 TextMessage textMessage = session.createTextMessage("张三,我已经收到消息了"); // 以上收到消息之后,从新创建生产者,然后在回执过去 MessageProducer producer = session.createProducer(recall_destination); producer.send(textMessage);
OK,这样就能相互通信了,你可以理解为通过两个通道进行的。
注意:这种方式毕竟会慢一些了,除非有及时性的,需要两端处理另外的事情,才这么多,因为涉及2步,都会有类似于“拜占庭将军问题”,因此解决还需要 持久化、多点部署,反而麻烦,按前面的场景还好。
小结:
1.这里大概介绍了activemq 的一些应答的及时,关于有些属性可以参考文档,具体问题具体分析~。~脱离场景谈性能都是耍流氓,这里也不会介绍性能问题,有测试的朋友可以告知一声。
2.如果有问题的,请大家指出,非常感谢。
相关推荐
activemq queue模式,事务、应答、转发模式、MessageConsumer的receive阻塞方法的测试
一个订阅通道,支持多个客户端监听,当某个客户端掉线后,再上线的时候可以收到它没有接收到的消息。
NULL 博文链接:https://zhaoshijie.iteye.com/blog/2090954
准备 1、python需要安装stomp,stomp包的安装比较麻烦,建议在网上直接下载.whl文件,然后本地安装 ...注意: 一般用python是通过stomp协议进行通讯 操作过程 1、生产方 prublishi.py import time import sys ...
学习总结资料
ActiveMQ-Topic订阅发布模式:参考博文:http://blog.csdn.net/ABAP_Brave/article/details/71211334
ActiveMQ_使用failover模式进行连接切换时,线程断开 ,ActiveMQ_使用failover模式进行连接切换时,线程断开
使用Camel配置ActiveMQ路由的实践方式
ActiveMQ的队列模式,初学ActiveMQ的,一个很好的体验、入门,代码注释很清楚,JMS的java使用步骤
activemq 的P2P模式学习记录,代码有详细的注释和讲解,以及对象进行简单的封装操作
#默认情况下activemq提供的是queue模式 true是可以使用topic,false是仅使用queue模式 spring.jms.pub-sub-domain: true # 设置连接的activemq服务器 spring.activemq.broker-url=failover:(tcp://10.0.1.227:61616,...
activemq activeMq笔记.docx
我下载的时候是 ActiveMQ 5.14.4 Release版 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们。消息传递指的是...
ActiveMQ请求应答(request-response)通信DEMO
apache-activemq Linux版本
最新activemq-cpp开发手册!
activeMQ的测试工具,用于发送和接收activeMQ消息,jar包形式的,安装完jdk之后用java -jar xxx.jar命令运行
activemq, Apache ActiveMQ镜像 欢迎来到 Apache ActiveMQis是一个高性能的Apache 2.0许可以消息代理和 JMS 1.1实现。正在启动要帮助你入门,请尝试以下链接:入门http://activemq.apache.org/version-
activemq书籍及工具 activemq书籍及工具 activemq书籍及工具 activemq书籍及工具 activemq书籍及工具
ActiveMQ高并发处理方案ActiveMQ高并发处理方案 超级字数补丁超级字数补丁