【mq读书笔记】mq事务消息
关于mq食物以什么样的方式解决了什么样的问题可以参考这里:
https://www.jianshu.com/p/cc5c10221aa1
上文中示例基于mq版本较低较新的版本中TransactionListener替换掉了TransactionCheckListener,整个流程有了一些改变,但还是小事务+异步的模式 不再详述
具体的实现中:
在本地事务执行之前会先send一个prepare消息。之后执行本地事务,带着一个transactionId。
最后在endTransaction里更新事务消息的状态:
=====================
org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendKernelImpl:
在消息发送之前,如果消息为prepare类型,则设置消息标准为prepare消息类型,方便消息服务期正确识别事务类型的消息。
========================
broker收到消息在sendMessageProcessor中:
如果是prepare消息执行prepareMessage方法。
事务消息存储在在未提交之前并不会存入消息原有主题,自然也不会被消费者消费。既然变更了主题,rocketmq通常会采用定时任务(单独的线程)去消费该主题,然后将该消息在满足特定条件下回复消息主题,进而被消费者消费。它与rocketmq定时消息的处理过程如出一辙。
=======================
endTransaction
Broker服务端的结束事务处理器为:EndTransactionProcessor。
如果结束事务动作为提交事务,则执行提交事务逻辑,其关键实现如下:
1.首先从结束事务请求命令中获取消息的物理偏移量(commitOffset)
2.然后回复消息的主题,消费队列,构建新的消息对象
3.然后将消息再次存储在commitlog文件中,此时的消息主题则为业务方发送的消息,将被转发到对应的消息消费队列,供消息消费者消费。
4.消息存储后,删除prepare消息,其实现方法并不是真正的删除,而是将prepare消息存储到RMQ_SYS_TRANS_OP_HALF_TOPIC主题中,表示该事务消息已经处理过,为未处理的事务回查提供查找依据。
事务回滚与提交的唯一差别是无需将消息恢复原主题,直接删除prepare消息即可。
==================
事务回查
执行完贝蒂事务返回本地事务状态为UN_KNOW时,结束事务时将不做任何处理,而是通过事务状态定时回查,以期得到发送端明确的事务操作(提交或回滚事务)
mq通过TransactionalMessageCheckService定时检查RMQ_SYS_TRANS_HALF_TOPIC中的消息,回查消息的事务状态。检测频率默认为1分钟。
重点看下其check方法:
获取RMQ_SYS_TRANS_HALF_TOPIC中的所有消息依次处理。
获取已处理消息的消息消费队列:RMQ_SYS_TRANS_OP_HALF_TOPIC。
处理已处理过的消息,这些消息不再发送事务状态回查请求。
经过一系列check之后
如果需要发送事务状态回查消息,则先将消息再次发送到RMQ_SYS_TRANS_HALF_TOPIC主题中(很奇怪不是吗)处于性能考虑。简化prepare消息队列的消息消费进度处理。后面回查的时候成功和失败进度都会前进,失败的话commitlog中的消息会再次回查,成功的话,op配合map会防止重复回查
【mq读书笔记】mq事务消息的更多相关文章
- 【mq读书笔记】顺序消息
注意异常情况导致整个消费无限重试 阻塞消费 mq支持局部消息顺序消费,可以确保同一个消息消费队列中的消息被顺序消费.看下针对顺序消息在整个消费过程中做的调整: 队列负载: DefaultMQPushC ...
- 【mq读书笔记】定时消息
mq不支持任意的时间京都,如果要支持,不可避免的需要在Broker层做消息排序,加上持久化方面的考量,将不可避免地带来巨大的性能消耗,所以rocketMQ只支持特定级别的延迟消息. 在Broker短通 ...
- 【mq读书笔记】消息队列负载与重新分配(分配 新队列pullRequest入队)
回顾PullMessageService#run: 如果队列总没有PullRequest对象,线程将阻塞. 围绕PullRequest有2个问题: 1.PullRequest对象在什么时候创建并加入p ...
- 【mq读书笔记】消费进度管理
从前2节可以看到,一次消费后消息会从ProcessQueue处理队列中移除该批消息,返回ProcessQueue最小偏移量,并存入消息进度表中.那消息进度文件存储在哪合适呢? 广播模式:同一个消费组的 ...
- 【mq读书笔记】消息消费队列和索引文件的更新
ConsumeQueue,IndexFile需要及时更新,否则无法及时被消费,根据消息属性查找消息也会出现较大延迟. mq通过开启一个线程ReputMessageService来准时转发commitL ...
- 【mq读书笔记】消息过滤机制
mq支持表达式过滤和类过滤两种模式,其中表达式又分为TAG和SQL92.类过滤模式允许提交一个过滤类到FilterServer,消息消费者从FilterServer拉取消息,消息经过FilterSer ...
- 【mq读书笔记】消息确认(失败消息,定时队列重新消费)
接上文的集群模式,监听器返回RECONSUME_LATER,需要将将这些消息发送给Broker延迟消息.如果发送ack消息失败,将延迟5s后提交线程池进行消费. 入口:ConsumeMessageCo ...
- 【mq读书笔记】消息消费过程(钩子 失败重试 消费偏移记录)
在https://www.cnblogs.com/lccsblog/p/12249265.html中,PullMessageService负责对消息队列进行消息拉取,从远端服务器拉取消息后将消息存入P ...
- 【mq读书笔记】消息拉取长轮训机制(Broker端)
RocketMQ并没有真正实现推模式,而是消费者主动想消息服务器拉取消息,推模式是循环向消息服务端发送消息拉取请求. 如果消息消费者向RocketMQ发送消息拉取时,消息未到达消费队列: 如果不启用长 ...
随机推荐
- python pickle 模块的使用详解
用于序列化的两个模块 json:用于字符串和Python数据类型间进行转换 pickle: 用于python特有的类型和python的数据类型间进行转换 json提供四个功能:dumps,dump,l ...
- django路径问题
1. 初始化项目结构 2.创建Django项目 使用pycharm打开项目 1.右击---->编辑配置 > 2.文件---->设置 > 3.文件---->设置 > ...
- 什么是 session 和 cookie
cookie 大家应该都熟悉,比如说登录某些网站一段时间后,就要求你重新登录:再比如有的同学很喜欢玩爬虫技术,有时候网站就是可以拦截住你的爬虫,这些都和 cookie 有关.如果你明白了服务器后端对于 ...
- Mybatis 批量更新遇到的小问题
小问题 记一个开发过程中因为小细节的遗漏而引发的 "莫名其妙",公司中有个2B(to B)供应链项目,持久层用的是 JPA,这里我就不吐槽 JPA 了,这种 SQL 嵌入在代码里的 ...
- C中二叉排序树的非递归和递归插入操作以及中序遍历代码实现【可运行】
C中二叉排序树的非递归和递归插入操作以及中序遍历代码实现[可运行] #include <stdio.h> #include <stdlib.h> typedef int Key ...
- leetcode114:valid-sudoku
题目描述 根据数独的规则Sudoku Puzzles - The Rules.判断给出的局面是不是一个符合规则的数独局面 数独盘面可以被部分填写,空的位置用字符'.'.表示 这是一个部分填写的符合规则 ...
- 剑指Offer-Python(1-5)
1.二维数组的查找 查找,其实就可以挨个进行比较就可以.又由于题目说明(每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序),因此如果利用类似于二分查找的方法,那么比较次数则会更少 ...
- Jmeter-全局变量跨线程组使用
一.前言 前面讲了如何使用正则表达式提取值,一般提取的值在同一个线程里,随意哪个请求都是可以引用的,那如果别的线程组也想引用怎么办呢?这时就涉及到一个全局变量的知识点了,话不多说,直接实例走起. 二. ...
- 用GitHub Pages搭建博客(六)
本篇介绍GitHub Pages网站加速 在上一篇提到如何对GitHub Pages配置自定义域名.其实,不论GitHub Pages的默认域名还是自定义域名,都使用了GitHub的CDN进行加速,虽 ...
- mysql三层体系
Mysql:是单进程多线程数据库. MySQL分层: mysql分三层:网络连接层, sql层, 存储引擎层,而网络连接层与sql层合称server层,故mysql又分server层合储存引擎层.第一 ...