工单处理流程异常分析

应用场景

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

事故异常体现

1、异常体现 从工单的流转记录发现,工单的状态从A->C->B,理论上工单的状态只能从A->B->C。结论1排除。

2、背景解释 一个工单创建完之后,会经历:

  • 工单创建完城-->状态新建、将新工单信息更新至ES(搜索引擎)
  • 工单内容审核-->状态已审核、将新工单信息更新至ES
  • 工单分配给指定工作人员-->状态已分配、将最新工单信息更新至ES
  • 其他操作-->状态改变-->将最新工单信息更新至ES
  • 说明:所有工单的操作都是异步的,没有固定顺序。

    3、事故异常分析 创单的顺序是优先于派单的。创单之后抛出一个写ES的MQ消息--消息A。派单之后也会抛出一个写ES的MQ消息--消息B。此处异常是MQ消息消费无序。正常拿到消息A、查询数据库的状态正确、可以推送ES消息、再接着拿到消息B、查询数据库的状态正确、可以推送ES消息。此处异常是,MQ消息消费无序。正常拿到消息A、查询数据库的状态正确、可以推送ES消息、再接着拿到消息B、查询数据库的状态正确、可以推送ES消息、因为推送ES没有加分布式锁、导致消息B那个时刻的工单数据被先写入ES、消息A那个时刻的工单数据后写入ES、导致ES的数据被覆盖、最终ES的最新版本的工单状态和数据库的工单状态不一致。

    4、解决方式 背景说明(续):写ES的MQ消息可以理解为并发出现、在工单创建的那一刻,所有改动工单状态的消息基本会在ms级别时间内到达。前提:在写ES的MQ消息中、携带更新完工单之后该工单的时间戳、作为工单的版本号。 方式一:暴力方式、直接在写ES的接口新增分布式锁、通过对比消息的版本号和工单数据库中的版本号、即可判定消息要舍弃还是写入ES。 方式二:仅对工单使用分布式锁、同时、在一定时间内(秒级)收集写ES的消息、并且对消息进行排序过滤、仅处理最新版本的工单消息写入ES。

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

    标签:游戏攻略