Skip to content

Latest commit

 

History

History
140 lines (106 loc) · 7.26 KB

File metadata and controls

140 lines (106 loc) · 7.26 KB

商品与订单服务技术升级方案

1. 现状分析

基于对现有代码库 (redbook-service-product, redbook-service-order) 的分析,当前实现主要处于基础功能阶段,与目标的高可用、高性能微服务架构存在一定差距:

  • 商品服务:已实现基础 CRUD 和 MongoDB 属性存储,但缺乏缓存层、全文检索和复杂的库存管理。
  • 订单服务:已实现基础下单和分布式锁扣减库存,但缺乏完整的状态机、风控、真实支付对接和可靠的分布式事务机制(目前先扣库存后异步创单存在风险)。
  • 架构层面:已引入 Spring Cloud Alibaba 组件(Nacos, Gateway),具备微服务基础,但未启用 Sentinel 熔断和 Seata 事务。

2. 商品服务升级方案

2.1 核心功能模块增强

2.1.1 商品分类与标签系统

  • 数据模型
    • 新增 Category 表:树形结构(id, parent_id, level, path),支持多级分类。
    • 新增 Tag 表和 ProductTag 关联表:实现灵活打标(如“新品”、“热销”)。
  • 实现建议
    • 分类树加载采用懒加载或一次性加载缓存至 Redis。

2.1.2 库存管理(实时追踪与预警)

  • 架构优化:将库存逻辑从 Product 表中剥离,建立独立的 ProductStock 表或服务。
  • Redis 预热:商品上架时将库存同步至 Redis。
  • Lua 脚本扣减:使用 Redis Lua 脚本保证 GETDECR 的原子性,防止超卖。
    if (redis.call('get', KEYS[1]) >= ARGV[1]) then
        return redis.call('decrby', KEYS[1], ARGV[1])
    else
        return -1
    end
  • 库存预警:定时任务扫描 Redis 库存,低于阈值发送报警消息(邮件/钉钉)。

2.1.3 商品搜索与筛选

  • 引入 Elasticsearch:替代 MySQL 的 LIKE 查询。
  • 数据同步
    • 方案 A (推荐):使用 Canal 监听 MySQL binlog,自动同步到 ES,解耦业务。
    • 方案 B (现有架构):在商品 CRUD 操作后发送 RabbitMQ 消息,搜索服务消费消息更新 ES。
  • 功能实现:利用 ES 的 BoolQuery 实现多条件组合筛选(价格区间、品牌、属性),使用 Analyzer 实现中文分词全文检索。

2.2 技术架构优化

2.2.1 多级缓存策略

  • L1 本地缓存 (Caffeine):缓存极热点数据(如秒杀商品详情),TTL 设置较短(如 5秒)。
  • L2 分布式缓存 (Redis)
    • 数据结构:Hash 结构存储商品详情 product:{id}
    • 缓存更新:采用 Cache-Aside 模式(先更新 DB,再删除缓存)。为防止缓存击穿,查询为空时设置空值并加短期过期时间。

2.2.2 数据库分库分表

  • 方案:使用 ShardingSphere-JDBC。
  • 策略t_product 表数据量较大时,可按 shop_idcategory_id 分库,或单纯按 id 范围分表。考虑到商品读多写少,建议优先做好读写分离。

2.2.3 CDN 加速

  • 实现:前端上传图片直传 OSS,后端只存 URL。在 OSS 侧配置 CDN 域名加速,后端返回给前端的 URL 替换为 CDN 域名。

3. 订单服务升级方案

3.1 核心业务流程重构

3.1.1 订单创建与风控

  • 风控前置:在进入下单逻辑前,调用风控服务(或组件)。
    • 规则:黑名单用户拦截、单用户单日下单限制、异常IP识别。
  • 流程优化
    1. 参数校验 & 风控。
    2. 获取商品信息 & 价格计算(应用优惠券)。
    3. 预扣库存 (Redis)。
    4. 生成订单 (状态: PENDING_PAYMENT)。
    5. 发送“订单创建延迟消息” (用于超时取消)。

3.1.2 订单状态机

  • 引入状态机模式管理订单状态流转,严禁随意 set(status)
  • 状态流转示例:
    • CREATED -> PAID (支付成功)
    • CREATED -> CANCELLED (用户取消/超时)
    • PAID -> SHIPPED (发货)

3.1.3 支付对接

  • 聚合支付设计:定义统一支付接口 PayService,实现 AliPayStrategy, WeChatPayStrategy
  • 回调处理:支付回调接口需保证幂等性,收到回调后更新订单状态,并记录支付流水。

3.2 分布式事务处理 (Saga 模式)

鉴于订单涉及库存、优惠券、积分等多个服务,建议采用 Saga 模式(编排式):

  • 正向流程

    1. 订单服务:创建订单 (Pending) -> 发送 OrderCreated 事件。
    2. 库存服务:监听 OrderCreated -> 扣减库存 -> 发送 StockDeducted 事件。
    3. 优惠券服务:监听 OrderCreated -> 锁定优惠券 -> 发送 CouponLocked 事件。
    4. 订单服务:监听 StockDeducted & CouponLocked -> 更新订单为 CONFIRMED。
  • 补偿流程 (回滚)

    • 如果库存扣减失败 -> 发送 StockFailed 事件。
    • 订单服务:监听 StockFailed -> 更新订单为 CANCELLED -> 发送 OrderCancelled 事件。
    • 优惠券服务:监听 OrderCancelled -> 解锁优惠券。

3.3 订单超时自动取消

  • 方案:RabbitMQ 延迟插件 或 死信队列 (DLX)。
  • 实现:下单成功后,发送一条 TTL 为 30分钟的消息到死信交换机。30分钟后消息进入死信队列,消费者检查该订单是否已支付,未支付则执行取消逻辑(释放库存、改状态)。

3.4 分库分表策略

  • 键选择user_id
  • 策略hash(user_id) % 32 分成 32 张表。这样同一用户的订单都在一张表,方便查询“我的订单”。
  • 运营查询:针对商家或后台查询(按 order_idshop_id),可建立 ES 宽表索引,将订单数据同步至 ES 提供复杂查询。

4. 服务间协作方案

4.1 通信方式

  • 查询类:使用 Feign (REST API) 同步调用,如订单详情页查询商品信息。
  • 交易类:使用 MQ 异步解耦,如支付成功后通知物流发货、通知用户中心增加积分。

4.2 数据一致性与对账

  • 最终一致性:依赖 MQ 的 ACK 机制和本地消息表,确保消息不丢失、不重复消费(幂等性)。
  • 对账系统
    • T+1 每日定时任务,拉取支付渠道(支付宝/微信)账单与本地订单表进行比对。
    • 异常处理:发现金额不一致或状态不一致,自动触发告警或进入人工处理队列。

5. 监控与运维要求

5.1 日志收集 (ELK)

  • Logstash/Filebeat:采集各服务 Docker 容器日志。
  • Elasticsearch:存储日志。
  • Kibana:展示日志面板,支持 traceId 全链路日志追踪。

5.2 监控 (Prometheus + Grafana)

  • Exporter:使用 micrometer-registry-prometheus 暴露 Spring Boot 指标 (JVM, JDBC, HTTP QPS)。
  • Grafana:配置仪表盘,监控系统负载、接口响应时间 (P99)、错误率。

5.3 熔断降级 (Sentinel)

  • 集成:引入 spring-cloud-starter-alibaba-sentinel
  • 规则
    • 限流:对“提交订单”接口设置 QPS 阈值。
    • 熔断:当 ProductClient 响应过慢或异常率高时,自动熔断,降级返回默认兜底数据(如“商品信息暂时不可用”),防止拖垮订单服务。