亿级分布式系统架构演进实战(一)- 总体概要
亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)
亿级分布式系统架构演进实战(三)- 横向扩展(数据库读写分离)
亿级分布式系统架构演进实战(四)- 横向扩展(负载均衡与弹性伸缩)
亿级分布式系统架构演进实战(五)- 横向扩展(缓存策略设计)
亿级分布式系统架构演进实战(六)- 横向扩展(监控与日志体系)
亿级分布式系统架构演进实战(七)- 横向扩展(安全防护设计)
亿级分布式系统架构演进实战(八)- 垂直拆分(领域划分及垂直分库设计)
亿级分布式系统架构演进实战(九)- 垂直拆分(服务间通信设计)
一、核心目标
解决跨服务数据一致性问题,平衡性能与一致性
- 强一致性:确保跨服务操作原子性,适用于金融等高敏感场景。
- 最终一致性:通过异步补偿机制,提升系统吞吐量和可用性。
- 可观测性:全链路监控事务状态,支持人工介入异常处理。
二、强一致性方案
1. Seata AT模式(自动补偿)
设计意图:
• 简化开发:通过全局锁机制自动回滚事务,减少业务侵入。
• 适用场景:电商订单创建(扣库存+生成订单)。
技术实现:
• 全局事务ID(XID):Seata客户端生成唯一ID,贯穿所有子事务。
• 数据快照:记录事务前后的数据镜像,用于自动回滚。
生产配置示例:
# Seata Server配置(Nacos注册中心)
seata:
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
优劣势:
• 优势:开发简单,适合传统事务迁移场景。
• 劣势:全局锁可能导致性能瓶颈(建议分库分表优化)。
2. XA两阶段提交(数据库原生支持)
设计意图:
• 强一致性保障:数据库原生支持,适合金融转账等高敏感场景。
技术实现:
• Phase 1(Prepare):所有参与者锁定资源,返回准备状态。
• Phase 2(Commit/Rollback):协调者根据Prepare结果提交或回滚。
代码示例:
// MySQL XA事务示例
XADataSource xaDataSource = ... // 获取XA数据源
XAResource xaRes = xaDataSource.getXAConnection().getXAResource();
Xid xid = new MyXid(); // 全局事务ID
try {
xaRes.start(xid, XAResource.TMNOFLAGS);
// 执行SQL操作(如扣款)
xaRes.end(xid, XAResource.TMSUCCESS);
xaRes.prepare(xid);
xaRes.commit(xid, false); // 提交事务
} catch (XAException e) {
xaRes.rollback(xid); // 回滚事务
}
优劣势:
• 优势:严格ACID,适合银行核心系统。
• 劣势:同步阻塞,性能较低(TPS < 500)。
3. TCC模式(手动补偿)
设计意图:
• 灵活控制:通过Try-Confirm-Cancel三阶段,支持自定义补偿逻辑。
技术实现:
• Try:预留资源(如冻结库存)。
• Confirm:提交事务(如确认扣减库存)。
• Cancel:回滚预留(如解冻库存)。
代码示例:
public interface InventoryTccService {
@TwoPhaseBusinessAction(name = "prepare", commitMethod = "confirm", rollbackMethod = "cancel")
boolean prepare(BusinessActionContext context, @BusinessActionContextParameter(paramName = "skuId") String skuId, int count);
boolean confirm(BusinessActionContext context);
boolean cancel(BusinessActionContext context);
}
生产配置:
• 幂等性保障:通过唯一事务ID避免重复提交。
• 超时控制:设置Try阶段最长等待时间(如30秒)。
优劣势:
• 优势:高性能,适合秒杀等高并发场景。
• 劣势:开发复杂,需手动实现补偿逻辑。
三、最终一致性方案
1. Saga模式(正向+逆向补偿)
设计意图:
• 长事务处理:通过事件驱动逐步执行事务,失败时逆向补偿。
技术实现:
• 正向操作:依次执行子事务(如创建订单 → 扣库存)。
• 补偿操作:逆向回滚(如取消订单 → 返还库存)。
代码示例:
// Saga流程定义(使用Apache Camel)
from("direct:createOrder")
.saga()
.compensation("direct:cancelOrder")
.to("bean:orderService?method=createOrder")
.to("bean:inventoryService?method=deductStock");
from("direct:cancelOrder")
.to("bean:orderService?method=cancelOrder")
.to("bean:inventoryService?method=restoreStock");
优劣势:
• 优势:支持复杂业务流程,适合电商订单。
• 劣势:补偿逻辑需覆盖所有失败场景。
2. 异步校对(定时补偿)
设计意图:
• 数据最终一致:通过定时任务检测并修复不一致状态。
技术实现:
• 定时任务:扫描事务表,检查未完成的事务。
• 补偿触发:对异常事务执行修复(如重试或回滚)。
生产配置示例:
-- 检测未完成订单
SELECT order_id
FROM orders
WHERE status = 'CREATED'
AND create_time < NOW() - INTERVAL '10 minutes';
优劣势:
• 优势:实现简单,适合对一致性要求不高的场景(如日志记录)。
• 劣势:修复延迟,可能影响用户体验。
3. 事务消息(RocketMQ)
设计意图:
• 可靠消息投递:确保本地事务与消息发送的原子性。
技术实现:
• 半消息:消息暂存Broker,不可被消费。
• 事务状态回查:Broker定期检查生产者事务状态。
代码示例:
// 发送事务消息
TransactionSendResult result = producer.sendMessageInTransaction(message, order);
if (result.getLocalTransactionState() == LocalTransactionState.ROLLBACK_MESSAGE) {
// 事务回滚处理
}
// 消费端幂等处理
if (redis.setnx(orderId, "PROCESSING") == 1) {
inventoryService.deductStock(orderId);
}
优劣势:
• 优势:高吞吐量(TPS > 10k),适合订单创建场景。
• 劣势:依赖消息队列可用性。
4. 本地事务消息表
设计意图:
• 去中心化事务:通过本地事务保证业务操作与消息写入的原子性。
技术实现:
- 业务表与消息表在同一个事务中写入。
- 定时任务扫描消息表,发送消息到MQ。
数据库表设计:
CREATE TABLE transaction_messages (
id BIGINT PRIMARY KEY,
topic VARCHAR(100),
payload TEXT,
status ENUM('PENDING', 'SENT'),
created_time TIMESTAMP
);
优劣势:
• 优势:不依赖MQ事务消息功能,兼容性高。
• 劣势:需额外维护消息表,增加数据库压力。
5. Transactional Outbox
设计意图:
• 可靠事件发布:通过数据库事务确保事件持久化,外部消费者轮询获取。
技术实现:
- 业务操作与事件写入同一事务。
- 独立进程轮询事件表,发布到MQ。
代码示例:
// 发布事件
@Transactional
public void createOrder(Order order) {
orderRepository.save(order);
outboxRepository.save(new OutboxEvent("order_created", order.getId()));
}
优劣势:
• 优势:解耦业务与消息发送,适合微服务架构。
• 劣势:增加轮询开销,可能引入延迟。
四、事务生命周期与监控
1. 事务状态记录
• 唯一事务ID:全局唯一标识符(如UUID)。
• 状态跟踪:记录事务的开始、提交、回滚状态。
数据库表设计:
CREATE TABLE transaction_logs (
tx_id VARCHAR(36) PRIMARY KEY,
service_name VARCHAR(50),
status ENUM('STARTED', 'COMMITTED', 'ROLLBACKED'),
created_time TIMESTAMP,
updated_time TIMESTAMP
);
2. 监控与告警
核心指标:
• 事务成功率:统计各服务事务成功/失败比例。
• 延迟分布:P50、P90、P99事务处理时间。
告警规则:
# Prometheus告警配置
groups:
- name: transaction-alerts
rules:
- alert: HighTransactionFailureRate
expr: sum(rate(transaction_failed_total[5m])) / sum(rate(transaction_total[5m])) > 0.05
labels:
severity: critical
annotations:
summary: "事务失败率超过5% (当前值: {{ $value }})"
人工介入流程:
- 异常标记:监控系统标记状态为“待处理”的事务。
- 人工处理:通过管理后台查看详情,触发补偿或通知开发。
五、方案对比与选型建议
方案 | 一致性 | 性能 | 复杂度 | 适用场景 |
---|---|---|---|---|
Seata AT | 强 | 中 | 低 | 传统业务迁移 |
XA两阶段提交 | 强 | 低 | 中 | 金融转账 |
TCC | 强 | 高 | 高 | 高并发秒杀 |
Saga | 最终 | 高 | 中 | 长流程事务(电商订单) |
事务消息 | 最终 | 高 | 中 | 异步通知场景 |
Transactional Outbox | 最终 | 中 | 高 | 微服务解耦 |