基于可靠消息的分布式事务解决方案

分布式事务解决方案的理论依据

  • CAP理论
  • BASE理论
  • 2PC协议
  • 3PC协议
  • Paxos算法
  • Raft一致性协议

分布式事务的几种解决方案

  • 基于数据库XA/JTA协议的方式;(需要数据库厂商支持;JAVA组件有atomikos等;)
  • 异步校对数据的方式;(支付宝/微信支付主动查询支付状态,对账单的形式)
  • 基于可靠消息(MQ)的解决方案;(异步场景;通用性较强;拓展性较高;)
  • TCC编程式解决方案;(Hmily等封装的DTX框架)

整体设计思路

  1. 可靠生产:保证消息一定发送到MQ服务;
  2. 可靠消费:保证消息取出来一定正确消费掉,达到最终多放数据达到一致;

可靠消息生产

  1. 记录消息发送
    • 为了确保数据一定成功发送到MQ:
      • 在同一事务中,增加一个记录表的操作,记录每一条发往MQ的数据以及它的发送状态;
  2. 修改消息发送状态
    • 利用MQ发布确认机制(confirm)
      • 开启确认发布确认机制后,MQ准确受理消息会返回回执;
      • 以RabbitMQ为例(注意:kafka不提供可靠消息机制)
# 生产者开启消息发送确认机制
spring:
  rabbitmq:
    publisher-confirms: true
    private final @NonNull RabbitTemplate amqpTemplate;

    @PostConstruct
    private void confirmCallBack() {
        amqpTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (log.isDebugEnabled()) {
                log.debug("MQ回调==>" + correlationData);
            }
            // ack为true,代表mq已经准确收到消息
            if (ack) {
                String id = correlationData.getId();
                Assert.isTrue(!StringUtils.isEmpty(id), "correlationData id can not null.");
                this.getBaseRepository()
                        .findById(id)
                        .flatMap(obj -> {
                            obj.setStatus(1);
                            return this.getBaseRepository().save(obj);
                        }).subscribe();
            }
        });
    }

    private void sentMsg(String json) {       
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(json.id);
        amqpTemplate.convertAndSend("msg.exchange","xxx",json,correlationData);
    }
  1. 记录定时检测
    • 如果出现回执没收到,消息状态修改失败等特殊情况:
      • 兜底的方案:定时检查消息表,超时没发送成功,再次重发;

可靠消息处理

  1. 正常情况:
    • 开启手动ACK模式,由消费者控制消息的重发/清除/丢弃;
    • 幂等性;防止重复处理,一次用户操作,只对应一次数据处理;
      • 幂等:根据ID或者业务数据,判断数据是否重复,重复就忽略;
  2. 消息重发:
    • 消费者处理失败,需要MQ再次重发给消费者;
    • 出现异常一般会重试几次,由消费者自身记录重试次数,并进行次数控制;
  3. 消息丢弃:
    • 消费者处理失败,直接丢弃或者转移到死信队列(DLQ)
      • 重试次数过多,消息内容格式错误等情况,通过线上预警机制通知运维人员-人工干涉;
# 消费者开启手动ACK,控制消息在MQ中的删除,重发...
spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: MANUAL
try{
  // 执行业务操作,同一个数据不能处理两次,根据业务情况去重,保证幂等行==>redis记录处理情况

  channel.basicAck(tag,false);
}catch(Exception e){
  // 异常情况: 根据需要去:重发/丢弃
  // 重发一定次数后,丢弃,日志警告==>防止重发多次,导致死循环
  channel.basicNack(tag,false,false);
  // 系统关键数据,永远是有人工干预
}

总结

  • 优点:
    1. 通用性强
    2. 拓展性强
    3. 方案成熟
  • 缺点
    1. 基于消息中间件,只适合异步场景;
    2. 消息处理会有延迟,需要业务上能够容忍;

建议

  • 不要使用分布式事务(尽量避免分布式事务,尽量将非核心事务做成异步)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容