基于对现有代码库 (redbook-service-product, redbook-service-order) 的分析,当前实现主要处于基础功能阶段,与目标的高可用、高性能微服务架构存在一定差距:
- 商品服务:已实现基础 CRUD 和 MongoDB 属性存储,但缺乏缓存层、全文检索和复杂的库存管理。
- 订单服务:已实现基础下单和分布式锁扣减库存,但缺乏完整的状态机、风控、真实支付对接和可靠的分布式事务机制(目前先扣库存后异步创单存在风险)。
- 架构层面:已引入 Spring Cloud Alibaba 组件(Nacos, Gateway),具备微服务基础,但未启用 Sentinel 熔断和 Seata 事务。
- 数据模型:
- 新增
Category表:树形结构(id,parent_id,level,path),支持多级分类。 - 新增
Tag表和ProductTag关联表:实现灵活打标(如“新品”、“热销”)。
- 新增
- 实现建议:
- 分类树加载采用懒加载或一次性加载缓存至 Redis。
- 架构优化:将库存逻辑从
Product表中剥离,建立独立的ProductStock表或服务。 - Redis 预热:商品上架时将库存同步至 Redis。
- Lua 脚本扣减:使用 Redis Lua 脚本保证
GET和DECR的原子性,防止超卖。if (redis.call('get', KEYS[1]) >= ARGV[1]) then return redis.call('decrby', KEYS[1], ARGV[1]) else return -1 end
- 库存预警:定时任务扫描 Redis 库存,低于阈值发送报警消息(邮件/钉钉)。
- 引入 Elasticsearch:替代 MySQL 的
LIKE查询。 - 数据同步:
- 方案 A (推荐):使用 Canal 监听 MySQL binlog,自动同步到 ES,解耦业务。
- 方案 B (现有架构):在商品 CRUD 操作后发送 RabbitMQ 消息,搜索服务消费消息更新 ES。
- 功能实现:利用 ES 的
BoolQuery实现多条件组合筛选(价格区间、品牌、属性),使用Analyzer实现中文分词全文检索。
- L1 本地缓存 (Caffeine):缓存极热点数据(如秒杀商品详情),TTL 设置较短(如 5秒)。
- L2 分布式缓存 (Redis):
- 数据结构:Hash 结构存储商品详情
product:{id}。 - 缓存更新:采用 Cache-Aside 模式(先更新 DB,再删除缓存)。为防止缓存击穿,查询为空时设置空值并加短期过期时间。
- 数据结构:Hash 结构存储商品详情
- 方案:使用 ShardingSphere-JDBC。
- 策略:
t_product表数据量较大时,可按shop_id或category_id分库,或单纯按id范围分表。考虑到商品读多写少,建议优先做好读写分离。
- 实现:前端上传图片直传 OSS,后端只存 URL。在 OSS 侧配置 CDN 域名加速,后端返回给前端的 URL 替换为 CDN 域名。
- 风控前置:在进入下单逻辑前,调用风控服务(或组件)。
- 规则:黑名单用户拦截、单用户单日下单限制、异常IP识别。
- 流程优化:
- 参数校验 & 风控。
- 获取商品信息 & 价格计算(应用优惠券)。
- 预扣库存 (Redis)。
- 生成订单 (状态: PENDING_PAYMENT)。
- 发送“订单创建延迟消息” (用于超时取消)。
- 引入状态机模式管理订单状态流转,严禁随意
set(status)。 - 状态流转示例:
CREATED->PAID(支付成功)CREATED->CANCELLED(用户取消/超时)PAID->SHIPPED(发货)
- 聚合支付设计:定义统一支付接口
PayService,实现AliPayStrategy,WeChatPayStrategy。 - 回调处理:支付回调接口需保证幂等性,收到回调后更新订单状态,并记录支付流水。
鉴于订单涉及库存、优惠券、积分等多个服务,建议采用 Saga 模式(编排式):
-
正向流程:
- 订单服务:创建订单 (Pending) -> 发送 OrderCreated 事件。
- 库存服务:监听 OrderCreated -> 扣减库存 -> 发送 StockDeducted 事件。
- 优惠券服务:监听 OrderCreated -> 锁定优惠券 -> 发送 CouponLocked 事件。
- 订单服务:监听 StockDeducted & CouponLocked -> 更新订单为 CONFIRMED。
-
补偿流程 (回滚):
- 如果库存扣减失败 -> 发送 StockFailed 事件。
- 订单服务:监听 StockFailed -> 更新订单为 CANCELLED -> 发送 OrderCancelled 事件。
- 优惠券服务:监听 OrderCancelled -> 解锁优惠券。
- 方案:RabbitMQ 延迟插件 或 死信队列 (DLX)。
- 实现:下单成功后,发送一条 TTL 为 30分钟的消息到死信交换机。30分钟后消息进入死信队列,消费者检查该订单是否已支付,未支付则执行取消逻辑(释放库存、改状态)。
- 键选择:
user_id。 - 策略:
hash(user_id) % 32分成 32 张表。这样同一用户的订单都在一张表,方便查询“我的订单”。 - 运营查询:针对商家或后台查询(按
order_id或shop_id),可建立 ES 宽表索引,将订单数据同步至 ES 提供复杂查询。
- 查询类:使用 Feign (REST API) 同步调用,如订单详情页查询商品信息。
- 交易类:使用 MQ 异步解耦,如支付成功后通知物流发货、通知用户中心增加积分。
- 最终一致性:依赖 MQ 的 ACK 机制和本地消息表,确保消息不丢失、不重复消费(幂等性)。
- 对账系统:
- T+1 每日定时任务,拉取支付渠道(支付宝/微信)账单与本地订单表进行比对。
- 异常处理:发现金额不一致或状态不一致,自动触发告警或进入人工处理队列。
- Logstash/Filebeat:采集各服务 Docker 容器日志。
- Elasticsearch:存储日志。
- Kibana:展示日志面板,支持
traceId全链路日志追踪。
- Exporter:使用
micrometer-registry-prometheus暴露 Spring Boot 指标 (JVM, JDBC, HTTP QPS)。 - Grafana:配置仪表盘,监控系统负载、接口响应时间 (P99)、错误率。
- 集成:引入
spring-cloud-starter-alibaba-sentinel。 - 规则:
- 限流:对“提交订单”接口设置 QPS 阈值。
- 熔断:当
ProductClient响应过慢或异常率高时,自动熔断,降级返回默认兜底数据(如“商品信息暂时不可用”),防止拖垮订单服务。