前言
在软件开发中,系统的架构设计和调用方式是确保系统高效、稳定运行的关键。XA模式与AT模式分别在分布式事务管理中扮演重要角色,决定了数据一致性与事务的管理机制。同时,调用方式的选择也直接影响到系统的响应速度与资源的使用效率。同步调用和异步调用是常见的两种调用模式,它们各有优缺点,适用于不同的应用场景。在本文中,我们将深入探讨这几种模式的原理及其应用,为开发者在实际开发过程中提供有价值的参考。
Seata
Seata支持四种不同的分布式事务解决方案:
- XA
- TCC
- AT
- SAGA
XA模式
XA规范是X/0pen 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准,XA规范 描述了全局的TM与局部的RM之间的接口,几乎所有主流的关系型数据库都对XA规范 提供了支持。Seata的XA模式如下:
一阶段的工作:
- RM注册分支事务到TC
- RM执行分支业务sql但不提交
- RM报告执行状态到TC
二阶段的工作: - TC检测各分支事务执行状态
- 如果都成功,通知所有RM提交事务
- 如果有失败,通知所有RM回滚事务
- RM接收TC指令,提交或回滚事务
RM一阶段的工作:
- 注册分支事务到TC
- 执行分支业务sql但不提交
- 报告执行状态到TC
TC二阶段的工作:
- TC检测各分支事务执行状态
- 如果都成功,通知所有RM提交事务
- 如果有失败,通知所有RM回滚事务
RM二阶段的工作:
- 接收TC指令,提交或回滚事务
XA模式的优点:
- 事务的强一致性,满足ACID原则。
- 常用数据库都支持,实现简单,并且没有代码侵入
XA模式的缺点:
- 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差
- 依赖关系型数据库实现事务
实现XA模式
1.修改application.yml文件(每个参与事务的微服务),开启XA模式:
seata:
data-source-proxy-mode: XA
2.给发起全局事务的入口方法添加@GlobalTransactional注解,本例中是0rderServicelmpl中的create方法:
3.重启服务并测试
AT模式
Seata主推的是AT模式,AT模式同样是分阶段提交的事务模型,不过缺弥补了XA模型中资源锁定周期过长的缺陷。
阶段一RM的工作:
- 注册分支事务
- 记录undo-log(数据快照)
- 执行业务sql并提交
- 报告事务状态
阶段二提交时RM的工作:
- 删除undo-log即可
阶段二回滚时RM的工作:
- 根据undo-log恢复数据到更新前
AT模式和XA模式的区别:
- XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。
- XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。
- XA模式强一致;AT模式最终一致
实现AT模式
首先,添加微服务对应的数据库:
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
然后,修改application.yml文件,将事务模式修改为AT模式:
seata
data-source-proxy-mode:AT #开启数据源代理的AT模式
RabbitMQ
高性能的异步通讯组件
- 同步通讯:如同打视频电话,双方的交互都是实时的。同一时刻只能跟一个用户进行视频电话。
- 异步通讯:如同发微信聊天,双方的交互不是实时的,不需要立刻回复,可以与多个用户进行通信。
同步调用
黑马商城的余额支付为例:
同步调用的优势:
- 时效性强,等待到结果后才返回
同步调用的方式存在下列问题:
- 拓展性差
- 性能下降
- 级联失败
异步调用
异步调用通常是基于消息通知的方式,包含三个角色:
- 消息发送者:投递消息的人,就是原来的调用者
- 消息接收者:接收和处理消息的人,就是原来的服务提供者
- 消息代理:管理、暂存、转发消息,你可以把它理解成微信服务器
支付服务不再同步调用业务关联度低的服务,而是发送消息通知到Broker。
具备下列优势:
- 解除耦合,拓展性强
- 无需等待,性能好
- 故障隔离,下游服务故障不影响上游业务
- 缓存消息,流量削峰填谷
异步调用的问题:
- 不能立即得到调用结果,时效性差
- 不确定下游业务执行是否成功
- 业务安全依赖于Broker的可靠性
MQ技术选型
MQ(MessageQueue),中文是消息队列,字面来看就是存放消息的队列。也就是异步调用中的Broker。
RabbitMQ | ActiveMQ | RocketMQ | Kafka | |
---|---|---|---|---|
公司/社区 | Rabbit | Apache | 阿里 | Apache |
开发语言 | Erlang | Java | Java | Scala&Java |
协议支持 | AMQP,XMPP,SMTP,STOMP | OpenWire,STOMP,REST,XMPP,AMQP | 自定义协议 | 自定义协议 |
可用性 | 高 | 一般 | 高 | 高 |
单机吞吐量 | 一般 | 差 | 高 | 非常高 |
消息延迟 | 微秒级 | 毫秒级 | 毫秒级 | 毫秒以内 |
消息可靠性 | 高 | 一般 | 高 | 一般 |
总结
本文对XA模式、AT模式以及同步调用与异步调用的特点和应用场景进行了详细分析。XA模式和AT模式各自在分布式事务中发挥着不同的作用,XA模式提供了更为严格的事务一致性,而AT模式则提供了更为灵活的事务处理方式。同步调用与异步调用在处理任务时分别注重响应时间和资源利用效率,开发者应根据具体需求合理选择。掌握这些模式的使用,有助于提高系统的性能和可靠性,优化系统架构设计。