一、架構設計與技術選型
典型分布式訂單系統架構:
[網關層] → [訂單服務] ←→ [分布式緩存]↑ ↓
[用戶服務] [支付服務]↓ ↓
[MySQL集群] ← [分庫分表中間件]
技術棧組合:
- Spring Boot 3.x
- Mybatis-Plus 3.5.x
- ShardingSphere 5.3.x
- Redis 7.x
- Seata 1.7.x
二、核心實現步驟
1. 訂單表設計(分庫分表場景)
CREATE TABLE t_order_0 (order_id BIGINT PRIMARY KEY COMMENT '雪花算法ID',user_id INT NOT NULL,amount DECIMAL(10,2) UNSIGNED,order_status TINYINT DEFAULT 0,create_time DATETIME DEFAULT CURRENT_TIMESTAMP,update_time DATETIME ON UPDATE CURRENT_TIMESTAMP,INDEX idx_user_status(user_id, order_status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. Mybatis-Plus增強配置
@Configuration
@MapperScan("com.orders.mapper")
public class MybatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 分頁插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 樂觀鎖插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
}
3. 分庫分表策略實現
# application-sharding.yml
spring:shardingsphere:datasource:names: ds0,ds1ds0: # 數據源配置ds1: rules:sharding:tables:t_order:actualDataNodes: ds${0..1}.t_order_${0..1}databaseStrategy:standard:shardingColumn: user_idshardingAlgorithmName: database-inlinetableStrategy:standard:shardingColumn: order_idshardingAlgorithmName: table-inlineshardingAlgorithms:database-inline:type: INLINEprops:algorithm-expression: ds${user_id % 2}table-inline:type: INLINEprops:algorithm-expression: t_order_${order_id % 2}
4. 訂單服務核心實現
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {@Autowiredprivate DistributedLockTemplate lockTemplate;@Transactional@GlobalTransactional // Seata分布式事務注解public Order createOrder(OrderDTO orderDTO) {// 冪等性檢查String lockKey = "order_create:" + orderDTO.getRequestId();return lockTemplate.execute(lockKey, 3000, () -> {Order order = convertToEntity(orderDTO);baseMapper.insert(order);// 發送領域事件applicationContext.publishEvent(new OrderCreatedEvent(this, order));return order;});}@DS("slave") // 指定讀從庫public Page<OrderVO> queryOrders(OrderQuery query, Pageable pageable) {return baseMapper.selectPage(new Page<>(pageable.getPageNumber(), pageable.getPageSize()),Wrappers.<Order>lambdaQuery().eq(Order::getUserId, query.getUserId()).between(Order::getCreateTime, query.getStartTime(), query.getEndTime()).orderByDesc(Order::getCreateTime)).convert(this::convertToVO);}
}
5. Mybatis二級緩存優化
<!-- OrderMapper.xml -->
<cache type="org.mybatis.caches.redis.RedisCache" eviction="LRU"flushInterval="600000"size="1024"readOnly="true"/>
三、性能優化實踐
- 熱點訂單緩存策略:
@Cached(name = "orderCache", expire = 30, timeUnit = TimeUnit.MINUTES)
public Order getOrderById(Long orderId) {return baseMapper.selectById(orderId);
}@CacheRefresh(refresh = 10, stopRefreshAfterLastAccess = 30, timeUnit = TimeUnit.MINUTES)
public Order getHotOrder(Long orderId) {// 高頻訪問訂單特殊處理
}
- 批量操作優化:
public void batchInsertOrders(List<Order> orders) {String sql = "<script>INSERT INTO t_order (...) VALUES " +"<foreach collection='list' item='item' separator=','>" +"(#{item.userId}, ...)" +"</foreach></script>";sqlSessionTemplate.insert(sql, orders);
}
四、分布式事務解決方案對比
方案 | 一致性 | 性能影響 | 適用場景 |
---|---|---|---|
本地事務 | 弱 | 無 | 單庫操作 |
XA協議 | 強 | 高 | 嚴格一致性金融交易 |
TCC | 最終 | 中 | 高并發長事務 |
SAGA | 最終 | 低 | 跨服務復雜業務流程 |
本地消息表 | 最終 | 中 | 異步可靠消息傳遞 |
五、生產環境注意事項
-
索引優化原則:
- 遵循最左前綴原則
- 避免在更新頻繁的列建索引
- 使用覆蓋索引減少回表
-
慢SQL監控配置:
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.slf4j.Slf4jImplmapUnderscoreToCamelCase: truedefault-executor-type: REUSEaggressive-lazy-loading: false# 開啟SQL監控
spring:datasource:hikari:register-mbeans: true
- 數據歸檔方案:
@Scheduled(cron = "0 0 3 * * ?")
public void archiveOrders() {LocalDateTime archiveTime = LocalDateTime.now().minusMonths(6);baseMapper.archiveOrders(archiveTime);
}
六、監控與排查工具鏈
- 日志跟蹤:SkyWalking + ELK
- SQL分析:Arthas + Mybatis-Plus性能分析插件
- 壓測工具:JMeter + Gatling
- 可視化監控:Grafana + Prometheus
典型監控指標:
- 訂單創建TPS
- 平均響應時間(P99)
- 慢SQL占比
- 緩存命中率
- 分庫分表均衡度
實戰總結:在Spring Boot分布式項目中實施訂單管理,需要重點把握分庫分表策略、緩存與數據庫的協同、分布式事務的選型這三個核心維度。通過Mybatis-Plus的增強功能可以顯著提升開發效率,同時要注意避免過度依賴ORM特性導致的性能問題。建議定期進行全鏈路壓測,持續優化數據訪問模式。