activemq - 浅析消息确认模式
2019独角兽企业重金招聘Python工程师标准>>>
前言
JMS的消息确认模式,定义了客户端(消息发送者或者消费者)与broker确认消息的方式,可以认为是客户端与Broker之间建立一种简单的“担保”机制。
在java的JMS标准 中,javax.jms.Session 包定义了4种消息确认模式,分别是:
- ** AUTO_ACKNOWLEDGE: ** 自动确认
- ** CLIENT_ACKNOWLEDGE : ** 客户端手动确认
- ** DUPS_OK_ACKNOWLEDGE: ** 自动批量确认
- ** SESSION_TRANSACTED: ** 事务提交并确认
其中,前面三个确认模式是针对消费端的,即消息被消息消费者接收之后,消费者应该如何告诉broker,它已经正确接收消息和处理消息。对于broker而言,只有接收到ACK指令,才会认为消息被正确的接收或者处理,这时,它会从broker的队列中,删除消息。
最后一个确认模式SESSION_TRANSACTED,为消息发送者提供了消息发送的事务处理方式。也就是指,消息发送者发送消息给broker后,broker只是暂存该消息,只有当发送者给broker进行事务确认消息后,broker才把消息加入到待发送队列中,换言之,如果消息发送者进行了事务回滚,消息会直接从broker中删除。
在 activemq中,通过下面API设置消息确认模式
Session createSession(boolean transacted, int acknowledgeMode)
- transacted:是否开启事务,设置为true后,acknowledgeMode的设置无效,但当transacted为false以及acknowledgeMode设置为 SESSION_TRANSACTED 时,会冲突并报异常
acknowledgeMode SESSION_TRANSACTED cannot be used for an non-transacted Session
- acknowledgeMode:即确认模式
其实,客户端与broker的通信是通过指令完成的。客户端在不同的ACK_MODE消息确认模式时,根据不同的时机发送ACK指令,每个ACK Command中会包含ACK_TYPE,那么broker端就可以根据ACK_TYPE来决定此消息的后续操作,例如消息需不需要重发,消息需不需要删除等。
ACK_TYPE如下:
- ** DELIVERED_ACK_TYPE: ** 消息"已接收",但尚未处理结束
- **STANDARD_ACK_TYPE : ** "标准"类型,通常表示为消息"处理成功",broker端可以删除消息了
- ** POSION_ACK_TYPE : ** 消息"错误",通常表示"抛弃"此消息,比如消息重发多次后,都无法正确处理时,消息将会被删除或者加入到DLQ(死信队列)
- ** REDELIVERED_ACK_TYPE : ** 消息需"重发",比如consumer处理消息时抛出了异常,broker稍后会重新发送此消息
- ** INDIVIDUAL_ACK_TYPE:** 表示只确认"单条消息",无论在任何ACK_MODE下
- ** UNMATCHED_ACK_TYPE: ** BROKER间转发消息时,接收端"拒绝"消息
下面我们来详细介绍一下四种消息确认模式。
AUTO_ACKNOWLEDGE
消息自动确认,意思是消费者接收消息后,不需要显示告诉broker已经接收到消息,而是由底层代码根据消息确认模式为AUTO_ACKNOWLEDGE,自动发送消息确认ack给broker,这样broker会从队列中删除消息。
有些文章说,采用AUTO_ACKNOWLEDGE模式,即使接收者正确接收消息后处理业务时发生了异常,接收者客户端也会被当作正常发送接收信息处理,那么这样不就在broker删除信息了吗?通过实验,事实并非如此,在接收消息处理消息过程中出现异常,broker会重发消息,或者把消息加入到死信队列中,这会在后面文章中介绍。
代码清单:消费者
public class Consumer {public static void main(String[] args) throws IOException {try {Connection connection = ActiveMQManager.createConnection();connection.start();Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //Queue queue = session.createQueue(Utils.QUEUE_NAME);MessageConsumer consumer = session.createConsumer(queue);consumer.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {try {System.out.println("-------- ----- --------- ");System.out.println("触发消息接收");TextMessage textMessage = (TextMessage) message;String text = textMessage.getText();handleMsg(text);System.out.println("成功处理消息 : " + text);} catch (JMSException e) {e.printStackTrace();}}});// 线程一直等待System.in.read();consumer.close();session.close();connection.stop();} catch (Exception e) {e.printStackTrace();}}// 处理消息private static void handleMsg(String msg) {System.out.println("准备处理消息 : " + msg);try {Thread.sleep(500); //500毫秒处理一个} catch (InterruptedException e) {e.printStackTrace();}//模拟处理的时候发生了异常//throw new RuntimeException("未知错误");}
}
CLIENT_ACKNOWLEDGE
由客户端(消费者)手动确认。我们在正确接收和处理消息后,需要使用message.acknowledge(),确认消息,否则,消息不会被broker删除。当我们重启消费者后,会重新取这些未确认的消息。
由于代码与上面雷同,所以这里只列出相关代码
consumer.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {try {System.out.println("-------- ----- --------- ");System.out.println("触发消息接收");TextMessage textMessage = (TextMessage) message;String text = textMessage.getText();handleMsg(text);message.acknowledge(); //确认消息,broker删除消息System.out.println("成功处理消息 : " + text);} catch (JMSException e) {e.printStackTrace();}}});
DUPS_OK_ACKNOWLEDGE
没研究,暂时不讨论。
SESSION_TRANSACTED
带事务的会话。在前面已经解释很清楚了,即消息发送者发送消息后,需要提交事务,否则消息不进入broker待发送队列中。
相关代码:
public void sendMessage(String message) throws JMSException {Session session = connection.createSession(true, Session.SESSION_TRANSACTED); //开启事务Queue queue = session.createQueue(Utils.QUEUE_NAME);MessageProducer producer = session.createProducer(queue);TextMessage toMessage = session.createTextMessage(message);producer.send(toMessage);session.commit(); //如果不提交事务,消息不会进入broker队列producer.close();session.close();}
代码
https://git.oschina.net/thinwonton/activemq-showcase
转载于:https://my.oschina.net/thinwonton/blog/995291
activemq - 浅析消息确认模式相关推荐
- RabbitMQ的5种队列_消息确认模式_入门试炼_第6篇
消费者从队列中获取消息,服务端如何知道消息已经被消费呢? 模式1:自动确认 只要消息从队列中获取,无论消费者获取到消息后是否成功消息,都认为是消息已经成功消费. 模式2:手动确认 消费者从队列中获取消 ...
- java确认rabbitmq_RabbitMQ的消息确认模式
基础篇https://edu.51cto.com/course/19845.html https://edu.51cto.com/course/19845.html https://edu.51cto ...
- springboot + rabbitmq 用了消息确认机制,感觉掉坑里了
最近部门号召大伙多组织一些技术分享会,说是要活跃公司的技术氛围,但早就看穿一切的我知道,这 T M 就是为了刷KPI.不过,话说回来这的确是件好事,与其开那些没味的扯皮会,多做技术交流还是很有助于个人 ...
- RabbitMQ(八):SpringBoot 整合 RabbitMQ(三种消息确认机制以及消费端限流)
说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同时消费端也采取了限流的措施, ...
- RabbitMQ:消费者ACK机制、生产者消息确认
文章目录 基础案例环境搭建: 环境: 1. 生产者发送消息确认 1.1 confirm 确认模式 1.2 return 退回模式 源代码 1.1.3 小结 2. 消费者签收消息(ACK) 2.1 代码 ...
- rabbitmq消息队列 ack机制(消息确认机制)和消息补偿机制
参考:https://blog.csdn.net/pan_junbiao/article/details/112956537 ack 机制就是消息在 生产者在发布消息以后,消息存在内存中,如果消息被确 ...
- activemq 消息阻塞优化和消息确认机制优化
一.消息阻塞优化 1.activemq消费者在从待消费队列中获取消息是会先进行预读取,默认是1000条(prefetch=1000).这样很容易造成消息积压. 2.可以通过设置prefetch的默认值 ...
- Java短信确认机制_JAVA 消息确认机制之 ACK 模式
JAVA 消息确认机制之 ACK 模式 CLIENT_ACKNOWLEDGE : 客户端手动确认, 这就意味着 AcitveMQ 将不会 "自作主张" 的为你 ACK 任何消息, ...
- RabbitMQ消息的确认模式
确认模式 包括两种自动确认.手动确认 自动确认 只要消息从队列中获取,无论消费者获取到消息后, 是否执行成功,都认为是消息已经成功消费. 手动确认 消费者从队列中获取消息后,服务器会将该消息标记为不可 ...
最新文章
- Bad connect ack with firstBadLink 192.168.*.*:50010
- 精读《REST,GraphQL,Webhooks gRPC 如何选型》
- Java是值传递还是引用传递?
- 被清华免试录取的围棋天才,横扫60位围棋大师的最强AI,竟然都输给了高中生!?...
- 关于JAVA_HOME, CLASSPATH和PATH的设置
- iOS多线程系列之GCD栅栏(barrier)实现同步锁
- android c 内存泄露,内存泄漏弄个明白
- spring源码-第五个后置处理器笔记
- 【综合类型第 16 篇】W3School 离线手册最新版下载
- 使用 TimeGAN 建模和生成时间序列数据
- 单元格下拉全选快捷键_excel全选快捷键是什么,excel表格全选快捷键是什么?...
- html5 drag api
- 优秀流程图和逻辑图画法的分析和借鉴
- python如何实现语音识别
- c++编写手机小游戏代码_C++代码实现贪吃蛇小游戏
- 运行错误 terminate called without an active exception
- 美国商会呼吁对ICO进行澄清
- 应届生求职网,职位信息函数爬取!!!稳得一比
- eSIM终端的生产流程的思考
- Python输出时出现乱码“�밴���������. . . ”的解决方案
热门文章
- 连续低频脑电图解码手臂运动,实现机械手臂的闭环自然控制
- 英特尔加注RISC-V:砸10亿投资,还加入其国际基金会
- 因为修苹果电脑太贵,美国人自学当上百万粉博主,网友:坐标深圳,不存在这问题...
- 微软旷视人脸识别100%失灵!北京十一学校校友新研究「隐身衣」,帮你保护照片隐私数据...
- 疫情之下,MWC 2020正式取消!此前仍有中国公司表态坚持参展
- 牛顿棺材板快盖不住了:用深度神经网络解决三体问题,提速一亿倍
- 各种AI模型拿来就能用!五大深度学习模型库大盘点
- Java动态追踪技术探究
- UWP crop image control
- 一个简单的路由映射,让你的树莓派通过SSH外网可访问