zoukankan      html  css  js  c++  java
  • 分布式事务,第三方接口一致性问题

    问题描述

    各个子系统数据一致性问题
    

    在过往单机系统的时代,把相关操作放在一个事务里,就能为我们解决数据一致性的问题。但在分布式系统和微服务架构盛行的今天,常常会遇到一个操作需要依赖多个外部服务的场景。要求我们自行解决各个系统数据一致性的问题。

    解决方案

    补偿事务
    

    互联网场景下,解决分布式系统的一致性问题,基于系统复杂性与吞吐量的考虑,多数团队不会选择类似两阶段提交,甚至三阶段提交的分布式事务。一个简单的补偿事务就足以解决多数问题。当然,如果系统都是自家可控的,第三方中间件也是不错的选择

    基本原理

    放弃强一致性,实现最终一致性
    

    不要ACID了,BASE就可以,系统间的数据在某个时间窗口可能是不一致的,通过添加一些补偿机制,来保证数据最终能够一致。只要数据的消费者感知不到这份不一致,系统总是可用的,就没有任何差异。举个不很恰当的例子,同事给你转了一万块,输完密码后的1秒内,其实银行扣除了他一万块,但并没有在你的账面上增加一万块(此时数据就是不一致的)。但1秒后,你的账面上到账一万块,此时数据最终一致了。作为数据的使用方,这1秒的不一致,你基本是感知不到的,最终系统的账面还是平的,于是乎,实现了子系统间的数据一致。

    实现的关键点

    接口幂等性
    

    考虑到宕机,服务异常,网络闪断等不可控因素,依赖的第三方接口需要支持幂等性。所谓幂等性,指接口支持重入,同等条件下,不管调用你几次,所产生的影响都应该是相同的。譬如说,使用支付接口转账,不管调用多少次,只要支付ID不变,都只会产生一次转账。

    DEMO

    用户提现,需要扣除本地系统余额,并调用第三份支付接口
    
    begin transaction
    
        //扣除本地库的余额
        //并生成一个全局唯一的支付ID(1)
        pay_id = deducted_balance()
        
        //MQ or 入库一条日志
        //记录本次扣除操作,并标记为扣除中(2)
        message_id = queue_message()
    
    end transaction
    
    //使用(1)生成的全局ID进行支付
    res = pay(pay_id)
    
    //支付结果一般会异步响应
    //如果有同步异常,则按需重试
    //【【== 此处应注意重用pay_id ==】】
    if should_retry(res)
      re_pay(pay_id)
    

    ~

    //处理异步响应支付结果
    
    //支付成功,更新(2)生成的消息状态
    if ok 
      update_ok(message_id)
      return
    
    
    //支付失败,调用第三方支付查询接口
    //二次校验是否没有支付
    res = query_pay_state(pay_id)
    
    //的确没有转账成功,回滚事务,把扣除的账补回去
    if error
      begin transaction
      
        rollback_banlance(pay_id)
        update_error(message_id)
        
      end transaction
      return
    
    //其实支付成功了
    update_ok(message_id)
    

    ~

    //考虑到异步回调的时延等问题,一般还会开个worker
    //定时去捞取(2)中的消息,并主动查询支付结果
    

    ~

    //以上仅为伪代码,忽略许多细节
    //譬如似涉及到金额的系统
    //应提供足量的日志,监控异常,定时核账
    

    MORE

    分布式系统事务一致性解决方案

    保证分布式系统数据一致性的6种方案

    拾零散记公众号

  • 相关阅读:
    ASIHTTPREQUEST 文档
    本地通知
    ASIHttpRequest 使用过程中,中文编码的问题
    讲讲最近自己的学习,谈谈未来的想法
    关于 ASP.NET MVC 4 如果管理用户
    [转贴]超级懒汉编写的基于.NET的微信SDK
    [转贴]实践:C++平台迁移以及如何用C#做C++包装层
    [转贴]Linq之动态查询
    [转贴]watin的一些例子
    [转贴]xcode帮助文档
  • 原文地址:https://www.cnblogs.com/WuYiStudio/p/10842042.html
Copyright © 2011-2022 走看看