【mq读书笔记】消息确认(失败消息,定时队列重新消费)
接上文的集群模式,监听器返回RECONSUME_LATER,需要将将这些消息发送给Broker延迟消息。如果发送ack消息失败,将延迟5s后提交线程池进行消费。
入口:ConsumeMessageConcurrentlyService#sendMessageBack
命令编码:RequestCode.CONSUMER_SEND_MSG_BACK;
MQClientAPIImpl#consumerSendMessageBack:
public void consumerSendMessageBack(
final String addr,
final MessageExt msg,
final String consumerGroup,
final int delayLevel,
final long timeoutMillis,
final int maxConsumeRetryTimes
) throws RemotingException, MQBrokerException, InterruptedException {
ConsumerSendMsgBackRequestHeader requestHeader = new ConsumerSendMsgBackRequestHeader();
RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.CONSUMER_SEND_MSG_BACK, requestHeader); requestHeader.setGroup(consumerGroup);
requestHeader.setOriginTopic(msg.getTopic());
requestHeader.setOffset(msg.getCommitLogOffset());
requestHeader.setDelayLevel(delayLevel);
requestHeader.setOriginMsgId(msg.getMsgId());
requestHeader.setMaxReconsumeTimes(maxConsumeRetryTimes); RemotingCommand response = this.remotingClient.invokeSync(MixAll.brokerVIPChannel(this.clientConfig.isVipChannelEnabled(), addr),
request, timeoutMillis);
assert response != null;
switch (response.getCode()) {
case ResponseCode.SUCCESS: {
return;
}
default:
break;
} throw new MQBrokerException(response.getCode(), response.getRemark());
}
public class ConsumerSendMsgBackRequestHeader implements CommandCustomHeader {
@CFNotNull
private Long offset;//消息物理偏移量
@CFNotNull
private String group;//消费组名
@CFNotNull
private Integer delayLevel;//延迟级别,mq不支持精确的定时消息调度,而是提供几个延时级别
private String originMsgId;//消息ID
private String originTopic;//消息主题
@CFNullable
private boolean unitMode = false;
private Integer maxReconsumeTimes;//最大重新消费次数,默认为16秒
服务端处理:
SendMessageProcessor#consumerSendMsgBack

获取消费组的订阅配置信息,如果配置信息为空返回配置组信息不存在
public class SubscriptionGroupConfig {
private String groupName;//消费组名
private boolean consumeEnable = true;//是否可以消费
private boolean consumeFromMinEnable = true;//是否允许从队列最小偏移量开始消费
private boolean consumeBroadcastEnable = true;//能否以广播模式消费,若为false只能以集群模式消费
private int retryQueueNums = 1;//重试队列个数,默认为1,每一个Broker上一个重试队列
private int retryMaxTimes = 16;消息最大重试次数
private long brokerId = MixAll.MASTER_ID;//masterId
private long whichBrokerWhenConsumeSlowly = 1;//如果消息堵塞,将转向改brokerId的服务器上拉取消息默认1
private boolean notifyConsumerIdsChangedEnable = true;//当消息发送变化时是否立即进行消息队列重新负载。
消费组订阅信息配置信息存储在Broker的${ROCKET_HOME}/store/config/subscription/Group.json。默认情况下BrokerConfig.autoCreateSubscriptionGroup默认为true,表示在第一次使用消费组配置信息时如果不存在,则使用上述默认值自动创建一个,如果为false,则只能通过客户端命令mqadmin updateSubGrouop创建后修改相关参数。

创建重试主题,重试主题名称:%RETRY%+消费组名称,并从重试队列汇总随机选择一个队列,并构建TopicConfig主题配置信息。

根据消息物理偏移量从commitlog文件中获取消息,同时将消息的主题存入属性中。

设置消息重试次数,如果消息已重试次数超过maxReconsumeTimes,再次改变newTopic主体为DLQ(%DLQ%),该主题的权限为只写,说明消息一旦进入到DLQ队列中,RocketMQ将不负责再次调度进行消费了需要人工干预。

根据原先的消息创建一个新的消息对象,重试消息会拥有自己的唯一消息ID并存入commitlog文件中,并不会去更新原先消息,而是会将原先的主题,消息ID存入消息的属性中,主题名称为重试主题,其他属性与原先消息保持相同。

消息持久化。
这里再重新回顾一下delayTimeLevel>0的情况:

在存入commitlog文件之前,如果消息的延迟级别delayTimeLevel大于0,替换消息的主题与队列为定时任务主题"SCHEDULE_TOPIC_XXXX",队列ID为延迟级别减1。再次将消息主题,队列存入消息的属性中。
ack消息存入CommitLog文件后,将依托RocketMQ定时消息机制在延迟时间到期后再次将消息拉取,提交消费线程池。ACK消息是同步发送的,如果在发送过程中出现错误,将记录所有发送ACK消息失败的消息,然后再次封装成ConsumeRequest,延迟5s执行。
【mq读书笔记】消息确认(失败消息,定时队列重新消费)的更多相关文章
- 【mq读书笔记】客户端处理消息(回调提交到异步业务线程池,pullRequest重新入队)
看一下客户端收到消息后的处理: MQClientAPIImpl#processPullResponse private PullResult processPullResponse( final Re ...
- Rabbitmq之高级特性——百分百投递消息&消息确认模式&消息返回模式实现
rabbitmq的高级特性: 如何保障消息的百分之百成功? 要满足4个条件:生产方发送出去,消费方接受到消息,发送方接收到消费者的确认信息,完善的消费补偿机制 解决方案,1)消息落库,进行消息状态打标 ...
- 【mq读书笔记】消息消费过程(钩子 失败重试 消费偏移记录)
在https://www.cnblogs.com/lccsblog/p/12249265.html中,PullMessageService负责对消息队列进行消息拉取,从远端服务器拉取消息后将消息存入P ...
- 【mq读书笔记】定时消息
mq不支持任意的时间京都,如果要支持,不可避免的需要在Broker层做消息排序,加上持久化方面的考量,将不可避免地带来巨大的性能消耗,所以rocketMQ只支持特定级别的延迟消息. 在Broker短通 ...
- 【mq读书笔记】mq事务消息
关于mq食物以什么样的方式解决了什么样的问题可以参考这里: https://www.jianshu.com/p/cc5c10221aa1 上文中示例基于mq版本较低较新的版本中TransactionL ...
- 【mq读书笔记】顺序消息
注意异常情况导致整个消费无限重试 阻塞消费 mq支持局部消息顺序消费,可以确保同一个消息消费队列中的消息被顺序消费.看下针对顺序消息在整个消费过程中做的调整: 队列负载: DefaultMQPushC ...
- 【mq读书笔记】mq消息消费
消息消费以组的的模式开展: 一个消费组内可以包含多个消费者,每一个消费组可订阅多个主题: 消费组之间有集群模式与广播模式两种消费模式:集群模式-主题下的同一条消息只允许被其中一个消费者消费.广播模式- ...
- 【mq读书笔记】消息消费队列和索引文件的更新
ConsumeQueue,IndexFile需要及时更新,否则无法及时被消费,根据消息属性查找消息也会出现较大延迟. mq通过开启一个线程ReputMessageService来准时转发commitL ...
- 【mq读书笔记】消息队列负载与重新分配(分配 新队列pullRequest入队)
回顾PullMessageService#run: 如果队列总没有PullRequest对象,线程将阻塞. 围绕PullRequest有2个问题: 1.PullRequest对象在什么时候创建并加入p ...
随机推荐
- 02 HTML 常见标记 选择器 样式
no.02今天主要学习了在web中的HTML CSS,并在其中制作了明信片,在制作明信片途中有几个知识点需要总结:1.HTML 全称hyper text markup language 超文本标记语言 ...
- Maven打包过程
1.安装maven 下载地址:http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.1/binaries/apache-maven- ...
- linux上性能调优常用命令及简介
1.综合命令:nmon.top:topas(aix) d :磁盘相关 c:cpu相关 m:内存相关 2.磁盘 2.1 测试顺序写性能dd if=/dev/zero of=/cdr/test.data ...
- 解决 ‘Could not fetch URL https://pypi.python.org’的问题
[前提]: win10下python3和python2共存环境,但是环境变量只配置了python3 [问题]: 用pip安装一个包执行pip2 install xxx的时候报错Fatal error ...
- phpstorm XDebug 调试
最近要实现php功能,要提供个接口提供访问,但是我就是个菜鸡,网上找了一堆,所以来提供踩坑心得了 参考文档: https://blog.csdn.net/yinhangbbbbb/article/de ...
- Java_Math类和Random类
Math类 java.lang.Math提供了一系列静态方法用于科学计算, 其方法的参数和返回值类型一般都为double型, 如果需要更加强大的数学运算能力计算高等数学中的相关内容, 可使用apach ...
- Java每日一考202011.4
1.JDK,JRE,JVM三者之间的关系 JDK包含JRE,JRE包含JVM JDK=JRE+JAVA的开发工具 JRE=JVM+JAVA核心类库 2.为什么要配置环境变量? 希望在任何路径下都能执行 ...
- cookie的简单介绍
思考: HTTP是一个无状态的协议,当一个客户端向服务端发送请求,在服务器返回响应后,连接就关闭了,在服务器端不保留连接信息. 当客户端发送多次请求且需要相同的请求参数的时候,应该如何处理?这个时候就 ...
- Java学习之AWT GUI编程
Java学习之AWT GUI编程 0x00 前言 既然前面提到了要重写冰蝎和一些反序列化工具,当然就不能随便说说而已.在编写这些工具还是要使用图形化工具来的方便一些,所以提前把GUI的框架给学习一遍. ...
- 莫小安 Linux下Redis的安装与配置
转载自--Linux下Redis的安装与配置 redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了 memcached的不足,它 ...