zoukankan      html  css  js  c++  java
  • 基于消息最终一致性解决方案

    问题思考

    订单系统和积分系统、财务记账系统在不同的系统中,如果订单操作成功,积分系统或财务系统没有对应的记录,就会造成数据不一致的情况,在这种背景下就需要有一套方案解决不一致的情况.
    方案图如下(龙果学院方案图):
     
    流程: 1预发消息 2dubbo返回 3确认并发送 4发送消息 5监听接收消息 6ACK确认已收到 7确认该条事务已处理成功;
     
         
     
     
    在这个案例中只列举两个系统之间的分布式事务,可以简单的理解为订单系统和记账系统

    示例图解释

    1.   蓝色虚线块:事务主动发起方,整个流程的起源,可以理解为在订单系统用户支付环节
    2.   紫色虚线块:消息服务子系统,将消息存入数据库,保证消息可靠性
    3.   绿色虚线块:事务被调用方,可以理解为记账系统对这次支付操作进行记账  
    4.   消息状态确认子系统:确认消息被成功消费,如果没有成功消费则作为补偿需要重新发送
    5.   消息恢复子系统:消息服务子系统的消息在多次发送之后仍没有被 “被动放应用系统” 确认消费则需要挂起,消息恢复子系统的任务就是让“消息服务子系统”的消息重新激活并发送,确保 “被动方应用系统”重新上线后可以消费掉此消息

    调用流程与容错处理

    异常流程:
    1.   若是1或2失败,则整个事务失败
    2.   若是3失败,则“消息状态子系统”扫描“消息服务子系统”中的存储在表中的预处理数据,并反向查询“主动应用系统”,如果“主动应用系统”查询到的订单状态是已处理完成,则调用“消息服务子系统”的储存的消息状态修改为已发送待消费接口并调用“消息服务子系统”的发送消息接口。
    3.   若是4失败,意味着“被动方应用系统”无法消费消息,那么必然不会执行7,此时就需要“消息恢复子系统”,定期检查“消息服务子系统”中的未确认已过期消息,并由“消息恢复子系统”重新发送出去,若消息已发出并走正常流程,则会被7确认已处理并消费
    4.   若是5失败,则和异常流程c一样,由“消息恢复子系统”处理
    5.   若是6失败,而7已经成功确认,则此条消息就会被重复消费,那么就体现出幂等的重要性,当“被动方应用系统”消费消息时需要做幂等处理,避免重复操作
    6.   若是7失败,此时的影响就是“被动方应用系统”成功消费并处理成功,但是未通知到“消息服务子系统”,那么当“消息恢复子系统”子系统重新发送消息时,需要做幂等处理,并重新走7流程;

    拓展

    •  图中紫色部分 消息服务子系统、消息确认子系统、消息恢复子系统设置成3个系统的原因是为了解耦
    •  消息服务子系统具备消息存储和消息发送功能, 主要体现在能力的提供,可作为公用服务
    •  消息恢复子系统和消息确认子系统则与业务密切相关, 需要根据消息查询具体业务是否处理成功,所以独立出来
    •  现实中业务量不大的情况下, 消息确认服务以模块的方式集成到调用业务系统中, 消息恢复子系统集成到消息子系统中, 从而只需要部署一个服务即可
    •  消息服务子系统中可以使用redis分布式锁提升性能(重复操作时)

    总结

    • 分布式事务中幂等判断非常重要
    • 网络是不可靠的,任何流程都有可能失败,需要多种失败补偿策略
    • 与基于DAO层分布式事务相比较; 优点是可控性强和可视化,代码解耦,削峰填谷; 缺点是只能用于通知型事务,时效性 不足, 编码量较多, 有代码侵入.
          

  • 相关阅读:
    数据恢复:解决ORA600[kghstack_free2][kghstack_err+0068]一例
    Oracle latch闩原理示意图
    MySQL Query Analyzer查询分析器
    Oracle GoldenGate Monitor架构图
    Oracle Row cache lock图解
    没有Metalink账号的同学可以观赏下,My Oracle Support的主界面
    Oracle Goldengate Director软件截面图
    Oracle Unbreakable Enterprise Kernel Faster than Redhat?
    从Win32过渡到MFC
    naked 函数调用
  • 原文地址:https://www.cnblogs.com/xieyanke/p/12143403.html
Copyright © 2011-2022 走看看