应用场景

C端用户提交工单、工单创建完成之后、会发布一条工单创建完成的消息事件(异步消息)、MQ消费者收到消息之后、会通知各处理器处理该消息、各处理器处理完后都会发布一条将该工单写入搜索引擎的消息、最终该工单出现在搜索引擎、被工单处理人检索和处理。

事故异常体现

1、异常体现

从工单的流转记录发现、工单的状态从A->C->B、理论上 工单的状态只能从A->B->C。此处能得出两个结论、1、各处理器处理完工单之后、状态有误;2、写入到搜索引擎的工单数据被本该更早写入引擎的数据覆盖了。

从监控数据发现、结论1排除。

2、背景解释

一个工单创建完之后、会经历

  • 工单创建完城-->状态新建、将新工单信息更新至ES(搜索引擎)
  • 工单内容审核-->状态已审核、将新工单信息更新至ES
  • 工单分配给指定工作人员-->状态已分配、将最新工单信息更新至ES
  • 其他操作-->状态改变-->将最新工单信息更新至ES

说明:
所有工单的操作都是异步的、没有固定顺序。
保证点:
写到ES之前从数据库所获取的工单信息都是最新的工单信息、无误。
案例中异常情况:
工单实际已经分配了工作人员(已分配状态)、可以查询到被分配的人、但是工单的状态显示是新建状态。

3、事故异常分析

1、创单的顺序是优先于派单的
2、创单之后抛出一个写ES的MQ消息--消息A
3、派单之后也会抛出一个写ES的MQ消息--消息B
4、如果MQ是有顺序的、按照顺序消费消息、MQ消费者消费第一个消息(消息A)肯定是比第二份消息(消息B)要快的、正常情况、工单是绝对没有问题。
(非正常情况、可能是ES自身写消息到集群、有快慢之分、第二个消息会先写完、此种情况基本忽略不计)

5、此处异常是、MQ消息消费无序

  正常拿到消息A、查询数据库的状态正确、可以推送ES消息、再接着拿到消息B、查询数据库的状态正确、可以推送ES消息、因为推送ES没有加分布式锁、导致消息B那个时刻的工单数据被先写入ES、消息A那个时刻的工单数据后写入ES、导致ES的数据被覆盖、最终ES的最新版本的工单状态和数据库的工单状态不一致。

4、解决方式

背景说明(续):写ES的MQ消息可以理解为并发出现、在工单创建的那一刻、所有改动工单状态的消息基本会在ms级别时间内到达。
前提:在写ES的MQ消息中、携带更新完工单之后该工单的时间戳、作为工单的版本号。

方式一:

  暴力方式、直接在写ES的接口新增分布式锁、通过对比消息的版本号和工单数据库中的版本号、即可判定消息要舍弃还是写入ES(不采取、会严重降低写ES的效率)
方式二:
  仅对工单使用分布式锁、同时、在一定时间内(秒级)收集写ES的消息、并且对消息进行排序过滤、仅处理最新版本的工单消息写入ES。

5、感想

1、有序的MQ消息资源会比较贵,还是要代码层保证数据稳定性。
2、验证异常论断的方式是、第一个大胆猜想、第二个必须保证有日志可追踪查询论证。

记一次RocketMQ消费非顺序消息引起的线上事故的更多相关文章

  1. RocketMQ学习笔记(9)----RocketMQ的Producer 顺序消息

    1. 顺序消息原理图 2. 什么是顺序消息? 消费消息的顺序要求同发送消息的顺序一致,在RocketMQ中,主要指的是局部顺序,即一类消息为满足顺序性,必须Producer单线程顺序发送,并且发送给到 ...

  2. 记一次线上事故的JVM内存学习

    今天线上的hadoop集群崩溃了,现象是namenode一直在GC,长时间无法正常服务.最后运维大神各种倒腾内存,GC稳定后,服务正常.虽说全程在打酱油,但是也跟着学习不少的东西. 第一个问题:为什么 ...

  3. 记一次真实的线上事故:一个update引发的惨案!

    目录 前言 项目背景介绍 要命的update 结语 前言   从事互联网开发这几年,参与了许多项目的架构分析,数据库设计,改过的bug不计其数,写过的sql数以万计,从未出现重大纰漏,但常在河边走,哪 ...

  4. RocketMQ源码 — 十、 RocketMQ顺序消息

    RocketMQ本身支持顺序消息,在使用上发送顺序消息和非顺序消息有所区别 发送顺序消息 SendResult sendResult = producer.send(msg, new MessageQ ...

  5. 聊一聊顺序消息(RocketMQ顺序消息的实现机制)

    当我们说顺序时,我们在说什么? 日常思维中,顺序大部分情况会和时间关联起来,即时间的先后表示事件的顺序关系. 比如事件A发生在下午3点一刻,而事件B发生在下午4点,那么我们认为事件A发生在事件B之前, ...

  6. 【mq读书笔记】顺序消息

    注意异常情况导致整个消费无限重试 阻塞消费 mq支持局部消息顺序消费,可以确保同一个消息消费队列中的消息被顺序消费.看下针对顺序消息在整个消费过程中做的调整: 队列负载: DefaultMQPushC ...

  7. RocketMQ专题2:三种常用生产消费方式(顺序、广播、定时)以及顺序消费源码探究

    顺序.广播.定时任务 前插 ​ 在进行常用的三种消息类型例子展示的时候,我们先来说一说RocketMQ的几个重要概念: PullConsumer与PushConsumer:主要区别在于Pull与Pus ...

  8. RocketMQ事务消费和顺序消费详解

    一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消费场景 在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成. ...

  9. 【转】RocketMQ事务消费和顺序消费详解

    RocketMQ事务消费和顺序消费详解 转载说明:该文章纯转载,若有侵权或给原作者造成不便望告知,仅供学习参考. 一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消 ...

  10. RocketMQ顺序消息

    rocketmq的顺序消息需要满足2点: 1.Producer端保证发送消息有序,且发送到同一个队列.2.consumer端保证消费同一个队列. 生产端: RocketMQ可以严格的保证消息有序.但这 ...

随机推荐

  1. 程序员天天 CURD,怎么才能成长,职业发展的思考 ?

    前言 关于程序员成长的话题,我前面写过一篇文章 - 程序员天天CURD,职业生涯怎么发展的思考. 现在回头看,对程序员这个职业发展的认识以及怎么发展还是有一些局限性.有一句话是这么说的:人的成长就是不 ...

  2. ES Monitoring 整理笔记

    Monitoring是elastic stack的监控模块,监控信息存在es索引中,并且可以通过kibana进行可视化的展示.(收集监控数据的方式从6.5版本起由Collectors-Exporter ...

  3. RocketMQ 事件驱动:云时代的事件驱动有啥不同?

    前言: 从初代开源消息队列崛起,到 PC 互联网.移动互联网爆发式发展,再到如今 IoT.云计算.云原生引领了新的技术趋势,消息中间件的发展已经走过了 30 多个年头. 目前,消息中间件在国内许多行业 ...

  4. vue子组件给父组件传值

    子组件: <template> <div class="app"> <input @click="sendMsg" type=&q ...

  5. JS基础--JavaScript实例集锦(初学)

    1.子节点childNodes: <!DOCTYPE html> <html> <head> <title>childNodes</title&g ...

  6. 保障升级:Splashtop 公布安全顾问委员会成员

    加利福尼亚州圣何塞,2020年12月17日-远程访问和远程支持解决方案的全球领导者 Splashtop Inc. 召集了网络安全性和合规性方面的领先专家,成立了该公司的安全顾问委员会.这组顾问有助于指 ...

  7. 【C#】爬取百度贴吧帖子 通过贴吧名和搜索关键词

    背景:最近喜欢看百度贴吧,因为其内容大多都是吧友的真实想法表达等等原因.但是通过网页去浏览贴吧,始终觉得不够简介,浏览帖子的效率不高,自己就萌发了通过自己爬取贴吧感兴趣的关键字内容,自己写了个winf ...

  8. MyBatis抛出BindingException异常可能是你忘了配置资源拷贝

    最近博主在搭建Mybatis项目时遇到了一问题,在一切配置妥当后,开始运行测试代码,但是此时控制台无情的抛出了异常: 开始寻找问题根源 咦?难道是我哪里写错,我的第一反应是我的xml配置文件哪里写错了 ...

  9. Prism IoC 依赖注入

    现有2个项目,SinglePageApp是基于Prism创建的WPF项目,框架使用的是Prism.DryIoc,SinglePageApp.Services是C#类库,包含多种服务,下面通过使用Pri ...

  10. conda错误 创建新环境conda create -n TF117 python=3.5时报错 An unexpected error has occurred. Conda has prepared the above report.

    创建新环境conda create -n TF117 python=3.5时报错 An unexpected error has occurred. Conda has prepared the ab ...