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 - 浅析消息确认模式相关推荐

  1. RabbitMQ的5种队列_消息确认模式_入门试炼_第6篇

    消费者从队列中获取消息,服务端如何知道消息已经被消费呢? 模式1:自动确认 只要消息从队列中获取,无论消费者获取到消息后是否成功消息,都认为是消息已经成功消费. 模式2:手动确认 消费者从队列中获取消 ...

  2. java确认rabbitmq_RabbitMQ的消息确认模式

    基础篇https://edu.51cto.com/course/19845.html https://edu.51cto.com/course/19845.html https://edu.51cto ...

  3. springboot + rabbitmq 用了消息确认机制,感觉掉坑里了

    最近部门号召大伙多组织一些技术分享会,说是要活跃公司的技术氛围,但早就看穿一切的我知道,这 T M 就是为了刷KPI.不过,话说回来这的确是件好事,与其开那些没味的扯皮会,多做技术交流还是很有助于个人 ...

  4. RabbitMQ(八):SpringBoot 整合 RabbitMQ(三种消息确认机制以及消费端限流)

    说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同时消费端也采取了限流的措施, ...

  5. RabbitMQ:消费者ACK机制、生产者消息确认

    文章目录 基础案例环境搭建: 环境: 1. 生产者发送消息确认 1.1 confirm 确认模式 1.2 return 退回模式 源代码 1.1.3 小结 2. 消费者签收消息(ACK) 2.1 代码 ...

  6. rabbitmq消息队列 ack机制(消息确认机制)和消息补偿机制

    参考:https://blog.csdn.net/pan_junbiao/article/details/112956537 ack 机制就是消息在 生产者在发布消息以后,消息存在内存中,如果消息被确 ...

  7. activemq 消息阻塞优化和消息确认机制优化

    一.消息阻塞优化 1.activemq消费者在从待消费队列中获取消息是会先进行预读取,默认是1000条(prefetch=1000).这样很容易造成消息积压. 2.可以通过设置prefetch的默认值 ...

  8. Java短信确认机制_JAVA 消息确认机制之 ACK 模式

    JAVA 消息确认机制之 ACK 模式 CLIENT_ACKNOWLEDGE : 客户端手动确认, 这就意味着 AcitveMQ 将不会 "自作主张" 的为你 ACK 任何消息, ...

  9. RabbitMQ消息的确认模式

    确认模式 包括两种自动确认.手动确认 自动确认 只要消息从队列中获取,无论消费者获取到消息后, 是否执行成功,都认为是消息已经成功消费. 手动确认 消费者从队列中获取消息后,服务器会将该消息标记为不可 ...

最新文章

  1. Bad connect ack with firstBadLink 192.168.*.*:50010
  2. 精读《REST,GraphQL,Webhooks gRPC 如何选型》
  3. Java是值传递还是引用传递?
  4. 被清华免试录取的围棋天才,横扫60位围棋大师的最强AI,竟然都输给了高中生!?...
  5. 关于JAVA_HOME, CLASSPATH和PATH的设置
  6. iOS多线程系列之GCD栅栏(barrier)实现同步锁
  7. android c 内存泄露,内存泄漏弄个明白
  8. spring源码-第五个后置处理器笔记
  9. 【综合类型第 16 篇】W3School 离线手册最新版下载
  10. 使用 TimeGAN 建模和生成时间序列数据
  11. 单元格下拉全选快捷键_excel全选快捷键是什么,excel表格全选快捷键是什么?...
  12. html5 drag api
  13. 优秀流程图和逻辑图画法的分析和借鉴
  14. python如何实现语音识别
  15. c++编写手机小游戏代码_C++代码实现贪吃蛇小游戏
  16. 运行错误 terminate called without an active exception
  17. 美国商会呼吁对ICO进行澄清
  18. 应届生求职网,职位信息函数爬取!!!稳得一比
  19. eSIM终端的生产流程的思考
  20. Python输出时出现乱码“�밴���������. . . ”的解决方案

热门文章

  1. 连续低频脑电图解码手臂运动,实现机械手臂的闭环自然控制
  2. 英特尔加注RISC-V:砸10亿投资,还加入其国际基金会
  3. 因为修苹果电脑太贵,美国人自学当上百万粉博主,网友:坐标深圳,不存在这问题...
  4. 微软旷视人脸识别100%失灵!北京十一学校校友新研究「隐身衣」,帮你保护照片隐私数据...
  5. 疫情之下,MWC 2020正式取消!此前仍有中国公司表态坚持参展
  6. 牛顿棺材板快盖不住了:用深度神经网络解决三体问题,提速一亿倍
  7. 各种AI模型拿来就能用!五大深度学习模型库大盘点
  8. Java动态追踪技术探究
  9. UWP crop image control
  10. 一个简单的路由映射,让你的树莓派通过SSH外网可访问