前言:
目前rocketmq更新已经更新了11篇博客了,预计接下来的2-3篇是暂时的更新进度了,准备更新一下springboot或者是jvm,mysql相关的专题出来,后续更新完事后,再分享一些实战性的案例出来,方便加深理解,也感谢一路看到这里的同仁;
1.屁话不多说,开局一张图(mq事务机制执行流程图)
2.分析从producer–>rocketmq–>consumer成功消费要打多少怪兽
1.订单系统推送消息到mq的过程是否会发生数据丢失?
当然可能会丢失:网络出现抖动,发送消息失败;
2.消息达到了MQ,MQ自己会导致数据丢失吗?
当然可能会丢失:producer写入数据到mq后,新数据是存储再os cache缓存中的,后面再异步刷盘的,之前有聊到过,那么如果此时mq出现宕机,内存中的数据就没了,数据就丢失了;
3.消息写入磁盘了,数据就万无一失吗?
点背啥都有可能会发生:数据没有做冗余备份,磁盘损坏了,一样丢失;
4.红包系统拿到了消息,就一定不会丢失了吗?
也不一定:消息的offset概念引出,默认情况下,mq消费组有可能自动提交已经消费的offset偏移量,如果此时还没有处理这个消息发送红包的情况下,mq可能直接自动提交这个1的offset到broker上去,标识已经成功处理了这条消息,点背:红包系统突然重启或者宕机,派发红包的时候,更新数据库失败了,此时内存中的消息1丢失,而且红包未派送成功。
2.1.rocketMQ设计的全链路消息零丢失方案总结:
2.1.1.producer发送消息到MQ的零丢失:
方案1:(同步发送消息+反复多次重试)
方案2:(事务消息机制),两者都有保证消息发送零丢失的效果,但是经过总体分析,事务消息方案的整体会更好一些;
2.1.2.MQ收到消息之后的零丢失
开启同步刷盘策略+raft主从架构同步机制,只要让一个broker收到消息之后同步写入磁盘,同时同步复制给其他的broker,然后再返回响应给生产者说写入成功,此时就可以保证MQ自己不会弄丢消息,但是性能会大大的降低;
2.1.3.consumer消费消息的零丢失
采用rocketMQ的消费者天然就可以保证处理完消息之后才会提交offset到broker中,只要记住不采用多线程异步处理消息的方式即可;
2.1.4.小总:
正常来讲一般都是金融,银行,订单系统等等这样的核心和钱相关的核心链路使用同步的方式生产和消费,对于其他大部分没有这么核心的场景和系统,即使丢失一些数据,也不会导致太大的问题,可以不必要采用同步的方式,否则大大的降低了性能,例如可以改成“同步发送消息+反复重试机制”;
3.事务消息机制的底层实现原理
3.1.half是什么?
half简单理解就是一个确定订单系统是否能和rocketmq正常通信,或者是否还活着,如果half没有响应成功,宕机了或者是故障了,这个时候订单系统就要执行一系列的回滚操作,比如对订单状态做一个更新,状态变成"关闭交易",通知支付系统进行退款处理,half实际上就是一个订单支付成功的消息,但是此时consumer是不可见的;
3.2.half消息是如何对消费者不可见的?
写入一条half消息到orderpaySuccessTopic中去,会定位到这个topic的一个messagequeue,然后定位到rockermq的一台broker机器上去,消息会写入commitLog,同时消息的offset会写入messagequeue对应的consumequeue,这个consumequeue是属于orderpaysucesstopic的,红包系统按道理是会从consumqueue中获取这个half消息的,为什么红包系统不可见这个half呢?看不到这个未提交的helf本质原因就是rocketmq一旦发现发送的消息是一个half消息,broker
不会将half消息的offset写入orderpaySucessTopic的consumequeue中去
【而是将这条half消息,写到自己内部的“RMQ_SYS_TRANS_HALF_TOPIC”】,这个topic对应的一个consumqueue中去;
3.3.什么情况下订单系统会收到half消息成功的响应呢?
当half消息写入到rockerMQ内部的“RMQ_SYS_TRANS_HALF_TOPIC”文件中了,此时就会认为half消息写入成功了,然后就会返回给订单系统;
3.4.如果订单系统一直没有做commit或者是rollback?
rocketmq会扫描自己处于half状态的消息,如果一直没有对这个消息执行commit/rollback。超过一定的时间,就会回调订单系统的接口,判断订单状态,如果是已经关闭订单,就会发送rollback删除之前的half消息;<如果一直没有执行commit/rollback,各种原因迟迟未做rollback/commit?定时任务,扫描consumequeue内部topic中的half消息,mq回调订单系统最多回调