【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 ...
随机推荐
- drf 权限校验设置与源码分析
权限校验 权限校验和认证校验必须同时使用,并且权限校验是排在认证校验之后的,这在源码中可以查找到其执行顺序. 权限校验也很重要,认证校验可以确保一个用户登录之后才能对接口做操作,而权限校验可以依据这个 ...
- Java学习的第五十天
1.求长方体的体积要求类中用但参数的方法去求 public class Cjava { public static void main(String[]args) { Box b1=new Box(1 ...
- JavaSE基础语法学习
标识符 表示类名的标识符用大写字母开始. 表示方法和变量的标识符用小写字母开始,后面的描述性词以大写开始. 注意 所有的标识符都应该以字母(A-Z 或者 a-z),美元符($).或者下划线(_)开始 ...
- leetcode131:letter-combinations-of-a-phone-number
题目描述 给出一个仅包含数字的字符串,给出所有可能的字母组合. 数字到字母的映射方式如下:(就像电话上数字和字母的映射一样) Input:Digit string "23"Outp ...
- 知识全聚集 .Net Core 技术突破 | 简单说说工作单元
知识全聚集 .Net Core 技术突破 | 简单说说工作单元 教程 01 | 模块化方案一 02 | 模块化方案二 其他教程预览 分库分表项目实战教程 Git地址: https://github.c ...
- HTML 5 <input> multiple 属性
<form action="demo_form.asp" method="get"> Select images: <input type=& ...
- python xmind转Excel(puppet洛洛原创)
需求:将xmind文件转为Excel文件,并添加UI界面操作以降低操作难度. 这个需求一句话就讲清楚了,但实际上还需要做很多工作: 1,了解Xmind文件结构 2,提取Xmind文件分支内容(重点) ...
- vue+echarts+datav大屏数据展示及实现中国地图省市县下钻
随着前端技术的飞速发展,大数据时代的来临,我们在开发项目时越来越多的客户会要求我们做一个数据展示的大屏,可以直观的展示用户想要的数据,同时炫酷的界面也会深受客户的喜欢. 大屏展示其实就是一堆的图表能够 ...
- Docker - 解决创建 tomcat 容器镜像却无法访问页面的问题
问题背景 查看 tomcat 镜像 docker images 运行并创建 tomcat 容器 docker -d -p 8888:8080 --name=tomcat2 tomcat:latest ...
- 使用GitHub API上传文件及GitHub做图床
本文介绍GitHub API基础及上传文件到仓库API,并应用API将GitHub作为图床 GitHub API官方页面 GitHub API版本 当前版本为v3,官方推荐在请求头中显示添加版本标识. ...