RocketMQ源码分析之RocketMQ事务消息实现原理中篇----事务消息状态回查

boolean isNeedCheck = (opMsg == null && valueOfCurrentMinusBorn > checkImmunityTime)

|| (opMsg != null && (opMsg.get(opMsg.size() - 1).getBornTimestamp() - startTime > transactionTimeout))

|| (valueOfCurrentMinusBorn <= -1); // @10

if (isNeedCheck) {

if (!putBackHalfMsgQueue(msgExt, i)) { // @11

continue;

}

listener.resolveHalfMsg(msgExt);

} else {

pullResult = fillOpRemoveMap(removeMap, opQueue, pullResult.getNextBeginOffset(), halfOffset, doneOpOffset); // @12

log.info(“The miss offset:{} in messageQueue:{} need to get more opMsg, result is:{}”, i,

messageQueue, pullResult);

continue;

}

}

newOffset = i + 1;

i++;

}

if (newOffset != halfOffset) { // @13

transactionalMessageBridge.updateConsumeOffset(messageQueue, newOffset);

}

long newOpOffset = calculateOpOffset(doneOpOffset, opOffset);

if (newOpOffset != opOffset) { // @14

transactionalMessageBridge.updateConsumeOffset(opQueue, newOpOffset);

}

本段代码比较长,却是事务状态回查的重点实现。

代码@1:先解释几个局部变量的含义。

getMessageNullCount :获取空消息的次数。

newOffset :当前处理RMQ_SYS_TRANS_HALF_TOPIC#queueId的最新进度。

i:当前处理消息的队列偏移量,其主题依然为RMQ_SYS_TRANS_HALF_TOPIC。

代码@2:这段代码应该不陌生,这是RocketMQ处理任务的一个通用处理逻辑,就是一个任务处理,可以限制每次最多处理的时间,RocketMQ为待检测主题RMQ_SYS_TRANS_HALF_TOPIC的每个队列,做事务状态回查,一次最多不超过60S,目前该值不可配置。

代码@3:如果removeMap中包含当前处理的消息,则继续下一条,removeMap中 的值是通过Step3中,填充的,具体实现逻辑是从RMQ_SYS_TRANS_OP_HALF_TOPIC主题中拉取32条,如果拉取的消息队列偏移量大于等于RMQ_SYS_TRANS_HALF_TOPIC#queueId当前的处理进度时,会添加到removeMap中,表示已处理过。

代码@4:根据消息队列偏移量i从消费队列中获取消息。

代码@5:如果消息为空,则根据允许重复次数进行操作,默认重试一次,目前不可配置。其具体实现为:

1、如果超过重试次数,直接跳出,结束该消息队列的事务状态回查。

2、如果是由于没有新的消息而返回为空(拉取状态为:PullStatus.NO_NEW_MSG),则结束该消息队列的事务状态回查。

3、其他原因,则将偏移量i设置为: getResult.getPullResult().getNextBeginOffset(),重新拉取。

代码@6:判断该消息是否需要discard(吞没,丢弃,不处理)、或skip(跳过),其依据如下:

1、needDiscard 依据:如果该消息回查的次数超过允许的最大回查次数,则该消息将被丢弃,即事务消息提交失败,不能被消费者消费,其做法,主要是每回查一次,在消息属性TRANSACTION_CHECK_TIMES中增1,默认最大回查次数为5次。

2、needSkip依据:如果事务消息超过文件的过期时间,默认72小时(具体请查看RocketMQ过期文件相关内容),则跳过该消息。

代码@7:处理事务超时相关概念,先解释几个局部变量:、

valueOfCurrentMinusBorn :该消息已存储的时间,等于系统当前时间减去消息存储的时间戳。

checkImmunityTime :立即检测事务消息的时间,其设计的意义是,应用程序在发送事务消息后,事务不会马上提交,该时间就是假设事务消息发送成功后,应用程序事务提交的时间,在这段时间内,RocketMQ任务事务未提交,故不应该在这个时间段向应用程序发送回查请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值