【中台·业务篇】订单中心与支付中心:通用业务能力沉淀与复用
发布时间:2026/9/27 6:58:45来源:尧图网络
前言用户中心解决了你是谁的问题订单中心解决的是你买了什么的问题支付中心解决的是钱怎么收的问题。这三者构成业务中台最核心的交易闭环。上一篇详解了用户中心本文将深入订单中心和支付中心的架构设计——从订单状态机、分布式事务保障、价格计算引擎到支付渠道聚合、退款流程、对账差错处理完整拆解这两个中心的业务能力沉淀方案。一、订单中心架构总览┌──────────────────────────────────────────────────────────────────────┐ │ 订单中心 (OC) │ │ │ │ ┌───────────────────┐ ┌───────────────────┐ ┌────────────────────┐ │ │ │ 订单创建服务 │ │ 订单状态服务 │ │ 订单查询服务 │ │ │ │ │ │ │ │ │ │ │ │ • 创建订单草稿 │ │ • 状态流转控制 │ │ • 订单列表 │ │ │ │ • 商品校验 │ │ • 超时自动关闭 │ │ • 订单详情 │ │ │ │ • 库存预扣 │ │ • 自动确认收货 │ │ • 多维度筛选 │ │ │ │ • 优惠计算 │ │ • 状态回滚 │ │ • 订单导出 │ │ │ │ • 价格计算 │ │ │ │ │ │ │ └────────┬──────────┘ └────────┬──────────┘ └────────────────────┘ │ │ │ │ │ │ ┌────────┴──────────────────────┴────────┐ ┌────────────────────┐ │ │ │ 价格计算引擎 │ │ 售后服务 │ │ │ │ │ │ │ │ │ │ • 商品价格(SKP定价) │ │ • 退款流程 │ │ │ │ • 优惠分摊(满减/折扣/优惠券) │ │ • 退货流程 │ │ │ │ • 运费计算(模板/重量/区域) │ │ • 换货流程 │ │ │ │ • 积分抵扣 │ │ • 售后状态机 │ │ │ │ • 最终实付金额 │ │ • 退款计算 │ │ │ └──────────────────────────────────────────┘ └────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────┐│ │ │ 订单ID生成器 ││ │ │ • Snowflake(分布式唯一ID) ││ │ │ • 业务编码(日期业务线序列号) ││ │ │ • 防重控制(幂等Token) ││ │ └──────────────────────────────────────────────────────────────────┘│ └──────────────────────────────────────────────────────────────────────┘二、订单创建全链路2.1 创建订单核心流程用户点击提交订单 步骤1: BFF层 → 校验请求参数 → 构建创建订单DTO │ ▼ 步骤2: 订单中心 → 生成订单号(Snowflake) │ → 幂等校验(检查client_token是否重复提交) │ ▼ 步骤3: 商品校验(调用商品中心SC) │ → 校验商品是否上架 │ → 校验SKU是否有效 │ → 校验购买限制(限购数量) │ ▼ 步骤4: 库存预扣(调用库存中心IC) │ → Redis分布式锁锁定SKU │ → 检查库存是否充足 │ → 预扣库存(预扣记录10分钟自动释放) │ ▼ 步骤5: 价格计算(价格引擎) │ → 查询商品价格(SKU定价) │ → 匹配优惠规则(满减/折扣/优惠券) │ → 计算优惠分摊到每个SKU │ → 计算运费(运费模板) │ → 计算积分抵扣 │ → 计算最终实付金额 │ ▼ 步骤6: 写入订单数据 │ → MySQL事务: 写订单主表 订单明细 订单日志 │ → 写入后发送MQ消息(order.created) │ ▼ 步骤7: 返回订单信息 │ → order_id, pay_amount, 支付方式列表 │ → 等待用户支付 │ ▼ 步骤8: 超时关闭(定时任务/延迟队列) │ → 30分钟未支付 → 自动关闭订单 │ → 释放预扣库存 │ → 释放优惠资格(优惠券归还)2.2 幂等控制// 幂等控制防止用户重复点击导致重复下单 // 方案1: 客户端幂等Token // 前端获取Token → 提交订单时携带 → 后端校验Token是否已使用 // Redis SETNX 实现幂等 public boolean checkAndConsumeIdempotent(String clientToken) { // clientToken 由前端在进入确认页时获取 // SETNX: key不存在则设置成功(返回1)已存在则失败(返回0) String key order:idempotent: clientToken; // 设置30分钟过期(与订单超时时间一致) Boolean result redis.opsForValue() .setIfAbsent(key, 1, 30, TimeUnit.MINUTES); return Boolean.TRUE.equals(result); // true → 首次提交放行 // false → 重复提交拒绝 } // 方案2: 业务唯一键 // 用户ID 商品ID 购买时间窗口 → 唯一索引 // 数据库层面保证不重复2.3 库存扣减方案库存扣减的三种模式 模式1: 下单预扣 支付实扣(推荐) 下单 → 预扣库存(Redis) → 支付成功 → 实扣库存(DB) 超时未付 → 释放预扣 优点: 防超卖用户体验好(下单即占库存) 缺点: 库存占用恶意下单占库存 模式2: 支付时扣减 下单 → 不扣库存 → 支付成功 → 扣减库存 优点: 不占库存 缺点: 可能超卖(库存不足时支付失败) 模式3: 预扣 支付实扣 风控(最佳实践) 下单 → 预扣 风控检查(限购/黑名单/设备指纹) → 正常用户: 预扣成功 → 风险用户: 拒绝预扣或限制预扣数量 // Redis预扣实现(Lua脚本保证原子性) local key stock:sku: .. ARGV[1] -- SKU库存Key local quantity tonumber(ARGV[2]) -- 扣减数量 local current tonumber(redis.call(GET, key) or 0) if current quantity then redis.call(DECRBY, key, quantity) -- 记录预扣明细 redis.call(HSET, stock:hold: .. ARGV[1], ARGV[3], quantity) -- 设置预扣过期时间 redis.call(EXPIRE, stock:hold: .. ARGV[1], 600) -- 10分钟 return 1 -- 扣减成功 else return 0 -- 库存不足 end三、订单状态机详解3.1 完整状态流转┌─────────────────────────┐ │ 初始状态 │ │ INIT (内部) │ └────────────┬────────────┘ │ 创建订单 ▼ ┌─────────────────────────┐ ┌─────────────│ 待支付 │ │ │ PENDING_PAYMENT │ │ └───────┬───────┬────────┘ │ │ │ 用户取消│ 支付成功│ 超时│未支付 │ │ │ ▼ ▼ ▼ ┌──────────────┐ ┌──────────┐ ┌──────────┐ │ 已取消 │ │ 待发货 │ │ 已关闭 │ │ CANCELED │ │ PAID │ │ CLOSED │ └──────────────┘ └────┬─────┘ └──────────┘ │ 商家发货 ▼ ┌──────────┐ │ 已发货 │ │ SHIPPED │ └────┬─────┘ │ 用户签收 │ (物流回调) ▼ ┌──────────┐ │ 待确认 │ │ DELIVERED│ └────┬─────┘ │ 自动确认 │ (7天/15天) ▼ ┌──────────┐ 售后申请 │ 已完成 │──────────────────┐ │COMPLETED │ │ └──────────┘ ▼ ┌──────────────┐ │ 售后中 │ │ AFTER_SALE │ └──┬───────┬───┘ 退款成功 │ │ 退货完成 ┌──────┘ └──────┐ ▼ ▼ ┌──────────┐ ┌──────────┐ │ 已退款 │ │ 已退货 │ │ REFUNDED │ │RETURNED │ └──────────┘ └──────────┘3.2 状态机实现// 状态机模式实现订单状态流转 // 1. 定义状态枚举 public enum OrderStatus { PENDING_PAYMENT(0, 待支付), PAID(10, 待发货), SHIPPED(20, 已发货), DELIVERED(30, 待确认), COMPLETED(40, 已完成), CANCELED(50, 已取消), CLOSED(60, 已关闭), REFUNDED(70, 已退款), RETURNED(80, 已退货); } // 2. 定义状态流转规则(状态转移表) public class OrderStateMachine { // 允许的状态转移: Map当前状态, 允许的目标状态列表 private static final MapOrderStatus, SetOrderStatus TRANSITIONS Map.of( PENDING_PAYMENT, Set.of(PAID, CANCELED, CLOSED), PAID, Set.of(SHIPPED, CANCELED), // 已支付可发货或取消退款 SHIPPED, Set.of(DELIVERED), DELIVERED, Set.of(COMPLETED), COMPLETED, Set.of() // 终态不可再流转(走售后流程) ); // 执行状态转移 public void transition(OrderStatus from, OrderStatus to) { SetOrderStatus allowed TRANSITIONS.get(from); if (allowed null || !allowed.contains(to)) { throw new IllegalStateException( String.format(非法状态转移: %s → %s, from, to)); } // 使用乐观锁更新(防并发) // UPDATE t_order SET order_status? // WHERE order_id? AND order_status? (旧状态) int rows orderMapper.updateStatus(orderId, to.getCode(), from.getCode()); if (rows 0) { throw new ConcurrentUpdateException(订单状态已被其他线程修改); } // 记录状态变更日志 orderLogMapper.insert(buildLog(orderId, from, to)); // 发送状态变更事件(MQ) eventPublisher.publish(new OrderStatusChangedEvent(orderId, from, to)); } }3.3 超时处理订单超时场景及处理 ┌────────────────────┬──────────────────┬───────────────────────────────┐ │ 超时场景 │ 超时时间 │ 处理逻辑 │ ├────────────────────┼──────────────────┼───────────────────────────────┤ │ 待支付超时 │ 30分钟 │ 关闭订单 释放库存 释放优惠 │ │ 待发货超时 │ 48小时 │ 商家告警 平台介入 │ │ 待签收超时 │ 物流签收回调 │ 物流签收后自动变更为待确认 │ │ 待确认超时 │ 7天/15天 │ 自动确认收货 │ │ 评价超时 │ 30天 │ 自动好评 │ │ 售后申请超时 │ 7天 │ 商家未处理自动同意 │ └────────────────────┴──────────────────┴───────────────────────────────┘ 技术方案对比: 方案A: 定时任务扫描(简单) → 每分钟扫描超时订单 → 性能差、延迟大 方案B: Redis延迟队列(推荐) → 下单时LPUSH到延迟队列 → 定时扫描到期任务 → 处理 → ACK删除 方案C: RocketMQ延迟消息(最佳) → 发送延迟消息(30分钟后投递) → 消费者收到消息后检查订单状态 → 未支付则关闭订单四、价格计算引擎4.1 价格计算流程┌─────────────┐ │ 商品原价 │ SKU单价 × 购买数量 │ itemPrice │ └──────┬──────┘ │ ▼ ┌─────────────┐ │ 优惠计算 │ 满减/折扣/优惠券/会员价 │ discount │ └──────┬──────┘ │ ▼ ┌─────────────┐ │ 优惠分摊 │ 将优惠金额按比例分摊到每个SKU │ allocate │ (为了退款时能精确退每个SKU的优惠) └──────┬──────┘ │ ▼ ┌─────────────┐ │ 运费计算 │ 运费模板(按重量/体积/区域/件数) │ shipping │ └──────┬──────┘ │ ▼ ┌─────────────┐ │ 积分抵扣 │ 100积分1元(可选) │ points │ └──────┬──────┘ │ ▼ ┌─────────────────────────────────────┐ │ 实付金额 商品总价 - 优惠 运费 - 积分抵扣 │ │ payAmount │ └─────────────────────────────────────┘4.2 优惠分摊算法场景: 订单含3个SKU总优惠100元 SKU A: 200元 → 分摊比例 200/500 40% → 分摊优惠 40元 SKU B: 200元 → 分摊比例 200/500 40% → 分摊优惠 40元 SKU C: 100元 → 分摊比例 100/500 20% → 分摊优惠 20元 分摊后: SKU A 实付 200 - 40 160元 SKU B 实付 200 - 40 160元 SKU C 实付 100 - 20 80元 总实付 160 160 80 400元 500 - 100 ✅ 取整问题处理: 优惠100元分摊到3个SKU(40%, 40%, 20%) → A: 40.00 B: 40.00 C: 20.00 → 整除OK 优惠99元分摊到3个SKU(40%, 40%, 20%) → A: 39.60 B: 39.60 C: 19.80 → 小数 处理: 最后一个SKU兜底 → A: 39.60(四舍五入40) B: 39.60(四舍五入40) → C: 99 - 40 - 40 19元 (兜底)五、支付中心架构5.1 支付中心核心设计┌──────────────────────────────────────────────────────────────────────┐ │ 支付中心 (PC) │ │ │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 收银台层 │ │ │ │ • 统一收银台UI(H5/App/小程序/PC多端) │ │ │ │ • 支付方式展示(按用户可用方式排序) │ │ │ │ • 优惠/红包在收银台展示 │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 交易核心层 │ │ │ │ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ │ │ 交易管理 │ │ 退款管理 │ │ 对账管理 │ │ │ │ │ │ • 创建交易 │ │ • 退款申请 │ │ • 日终对账 │ │ │ │ │ │ • 查询交易 │ │ • 退款执行 │ │ • 差错处理 │ │ │ │ │ │ • 关闭交易 │ │ • 退款查询 │ │ • 自动平账 │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 渠道适配层 │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ │ │ 统一接口 │ │ │ │ │ │ createPayment() / queryPayment() / closePayment() │ │ │ │ │ │ refund() / queryRefund() / notify() │ │ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │微信适配器│ │支付宝 │ │银联适配器│ │余额支付 │ │ │ │ │ │ │ │适配器 │ │ │ │适配器 │ │ │ │ │ │JSAPI │ │当面付 │ │网关支付 │ │余额扣减 │ │ │ │ │ │Native │ │手机网站 │ │扫码 │ │ │ │ │ │ │ │APP │ │APP支付 │ │ │ │ │ │ │ │ │ │H5 │ │ │ │ │ │ │ │ │ │ │ │小程序 │ │ │ │ │ │ │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 风控与安全层 │ │ │ │ • 交易限额(单笔/日累计/月累计) │ │ │ │ • 频次控制(同账号/同IP/同设备) │ │ │ │ • 黑名单(账号/设备/IP/银行卡) │ │ │ │ • 签名验签(RSA/HMAC) │ │ │ │ • 交易加密(敏感信息加密传输) │ │ │ └────────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────┘5.2 渠道适配器模式// 统一支付接口 public interface PaymentChannel { // 创建支付 PaymentResult createPayment(PaymentRequest request); // 查询支付状态 PaymentStatus queryPayment(String paymentId); // 关闭支付 void closePayment(String paymentId); // 退款 RefundResult refund(RefundRequest request); // 查询退款 RefundResult queryRefund(String refundId); // 异步通知处理 NotifyResult handleNotify(MapString, String params); } // 微信支付适配器 Component public class WechatPayAdapter implements PaymentChannel { Override public PaymentResult createPayment(PaymentRequest request) { // 1. 构建微信支付请求 WxPayRequest wxRequest WxPayRequest.builder() .appId(wxConfig.getAppId()) .mchId(wxConfig.getMchId()) .outTradeNo(request.getPaymentId()) .totalFee(request.getAmount()) // 微信用分 .body(request.getSubject()) .notifyUrl(wxConfig.getNotifyUrl()) .build(); // 2. 调用微信API WxPayResponse response wxPayClient.unifiedOrder(wxRequest); // 3. 转换为统一结果 return PaymentResult.builder() .paymentId(request.getPaymentId()) .payUrl(response.getCodeUrl()) // Native支付返回二维码 .prepayId(response.getPrepayId()) // JSAPI返回预支付ID .build(); } Override public NotifyResult handleNotify(MapString, String params) { // 1. 验签 if (!wxPayClient.verifySign(params)) { return NotifyResult.fail(验签失败); } // 2. 解析通知内容 String tradeNo params.get(transaction_id); String outTradeNo params.get(out_trade_no); String tradeStatus params.get(trade_state); // 3. 返回统一结果 return NotifyResult.success(tradeNo, outTradeNo, SUCCESS.equals(tradeStatus)); } } // 支付路由: 根据条件选择最优渠道 public class PaymentRouter { public PaymentChannel route(PaymentRequest request) { // 策略1: 用户指定的支付方式优先 if (request.getPayMethod() ! null) { return channelMap.get(request.getPayMethod()); } // 策略2: 按费率选择最低成本渠道 // 策略3: 按渠道可用性选择(降级) // 策略4: 按限额选择(大额走银联小额走微信) return selectOptimalChannel(request); } }5.3 支付回调处理异步通知处理流程(关键: 幂等 验签): ┌──────────────────────────────────────────────────────────────────┐ │ 第三方支付平台 │ │ (微信/支付宝) │ │ → 用户完成支付 │ │ → 异步通知支付中心 │ └──────────────────────────┬───────────────────────────────────────┘ │ POST /payment/notify/wechat ▼ ┌──────────────────────────────────────────────────────────────────┐ │ 支付中心 - 回调处理 │ │ │ │ 步骤1: 验签 │ │ → 用微信公钥验证签名 → 失败返回错误 │ │ │ │ 步骤2: 幂等检查 │ │ → Redis: payment:notify:{trade_no} → 是否已处理过 │ │ → 已处理 → 直接返回成功(微信会重试需幂等) │ │ → 未处理 → 继续 │ │ │ │ 步骤3: 更新支付单状态 │ │ → 乐观锁: UPDATE payment SET statusPAID │ │ WHERE payment_id? AND statusPENDING │ │ → rows0 说明已被其他线程处理 → 幂等返回 │ │ │ │ 步骤4: 通知订单中心(MQ消息) │ │ → 发送 payment.success 消息 │ │ → 订单中心消费 → 更新订单状态为已支付 │ │ → 库存中心消费 → 预扣转实扣 │ │ → 营销中心消费 → 核销优惠券、发放积分 │ │ │ │ 步骤5: 返回成功 │ │ → 返回 xmlreturn_codeSUCCESS/return_code/xml │ │ → 微信收到成功后不再重试 │ └──────────────────────────────────────────────────────────────────┘六、退款与对账6.1 退款流程退款全流程: 用户申请退款 │ ▼ ┌──────────────┐ │ 退款申请 │ → 订单中心发起售后 │ (REFUND_REQ) │ → 支付中心创建退款单 └──────┬───────┘ │ ▼ ┌──────────────┐ 商家审核(7天超时自动同意) │ 退款审核 │ → 商家同意 / 拒绝 │ (REFUND_ │ → 拒绝 → 退款关闭 → 用户可申诉 │ REVIEWING) │ └──────┬───────┘ │ 商家同意 ▼ ┌──────────────┐ │ 退款执行 │ → 调用渠道退款接口 │ (REFUNDING) │ → 微信退款API: /secapi/pay/refund └──────┬───────┘ │ ├── 退款成功 → REFUND_SUCCESS │ → 通知订单中心 → 更新订单为已退款 │ → 通知库存中心 → 回滚库存 │ → 通知营销中心 → 退还优惠/积分 │ ├── 退款失败 → REFUND_FAILED │ → 人工介入(余额不足/渠道异常) │ └── 退款处理中 → 等待渠道异步回调 → 退款回调通知 → 更新为成功/失败 退款金额计算: 全额退款 实付金额 部分退款 申请金额(不能超过实付) 优惠券/积分处理: → 退款金额含优惠 → 优惠券不退(已核销) → 退款金额不含优惠 → 优惠券可退(归还用户) → 积分按比例退还6.2 日终对账T1对账流程: ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 平台支付流水 │ │ 第三方流水 │ │ 银行流水 │ │ (支付中心DB) │ │ (微信/支付宝)│ │ (资金账户) │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ │ └────────┬───────────┘ │ ▼ │ ┌──────────────┐ │ │ 对账引擎 │◄───────────────────────┘ └──────┬───────┘ │ ┌────────┼────────┐ ▼ ▼ ▼ ┌─────────┐┌─────────┐┌──────────┐ │ 平账 ││ 差错 ││ 挂账 │ │ (一致) ││ (不符) ││ (单边) │ └─────────┘└────┬────┘└────┬─────┘ │ │ ▼ ▼ 人工处理 自动补单/退款 差错类型: 长款: 平台无记录, 第三方有 → 可能重复回调 → 退款给用户 短款: 平台有记录, 第三方无 → 可能掉单 → 查单补回调 金额不符: 两边金额不一致 → 人工介入调查 退款差错: 退款成功但平台未更新 → 补偿更新 对账文件格式(每日凌晨下载): 微信: https://api.mch.weixin.qq.com/.../downloadbill 支付宝: https://openapi.alipay.com/.../alipay.data.dataservice.bill.downloadurl.query七、分布式事务保障7.1 交易链路的事务挑战下单支付涉及多个服务: 订单服务 → 库存服务 → 营销服务 → 支付服务 如果用2PC(XA)强一致性事务: → 性能极差(全局锁) → 不适合高并发场景 → 不适合微服务架构 推荐方案: 最终一致性 事务消息 方案1: 本地消息表(可靠消息最终一致) → 订单服务本地事务: 写订单 写本地消息表 → 定时扫描消息表 → 发送MQ → 消费者服务保证幂等消费 方案2: RocketMQ事务消息 → 半消息 → 本地事务 → commit/rollback → 回查机制确保消息最终一致 方案3: SEATA Saga模式(长事务) → 定义补偿流程 → 每步有正向操作和补偿操作 → 失败时执行补偿(已成功的步骤反向回滚)7.2 RocketMQ 事务消息实现// 事务消息: 确保订单创建和库存扣减的最终一致性 // 步骤1: 发送半消息 TransactionMQProducer producer new TransactionMQProducer(order_group); producer.setTransactionListener(new TransactionListener() { // 执行本地事务 Override public LocalTransactionState executeLocalTransaction(Message msg, Object arg) { String orderId msg.getKeys(); try { // 本地事务: 创建订单 预扣库存 orderService.createOrder(orderDto); inventoryService.preDeduct(orderDto.getItems()); // 本地事务成功 → 提交消息 return LocalTransactionState.COMMIT_MESSAGE; } catch (Exception e) { // 本地事务失败 → 回滚消息 return LocalTransactionState.ROLLBACK_MESSAGE; } } // 事务回查(网络异常等情况下,Broker主动回查) Override public LocalTransactionState checkLocalTransaction(MessageExt msg) { String orderId msg.getKeys(); // 检查本地事务是否成功 Order order orderService.getById(orderId); if (order ! null order.getStatus() ! OrderStatus.INIT) { return LocalTransactionState.COMMIT_MESSAGE; } return LocalTransactionState.UNKNOW; // 继续等待 } }); // 步骤2: 发送事务消息 Message msg new Message(order_topic, create, orderId, JSON.toJSONBytes(orderDto)); producer.sendMessageInTransaction(msg, null); // 步骤3: 库存服务消费消息(幂等) RocketMQMessageListener(topic order_topic, consumerGroup inventory_group) public class InventoryConsumer implements RocketMQListenerOrderMessage { Override public void onMessage(OrderMessage message) { // 幂等检查 if (redis.setIfAbsent(consume: message.getOrderId(), 1, 24h)) { inventoryService.deduct(message.getItems()); } } }八、性能优化与高可用8.1 订单系统性能优化┌──────────────────────────────────────────────────────────────────┐ │ 性能优化策略 │ ├──────────────────┬───────────────────────────────────────────────┤ │ 读写分离 │ 订单查询走从库, 写操作走主库 │ ├──────────────────┼───────────────────────────────────────────────┤ │ 分库分表 │ 按user_id分库, 每库按create_time分表 │ │ │ → 避免单表数据过大 │ ├──────────────────┼───────────────────────────────────────────────┤ │ 热点数据缓存 │ 订单详情缓存Redis(5分钟) │ │ │ → 减少DB查询 │ ├──────────────────┼───────────────────────────────────────────────┤ │ 异步化 │ 非核心逻辑异步化(MQ解耦) │ │ │ → 积分发放、消息通知、统计等 │ ├──────────────────┼───────────────────────────────────────────────┤ │ 库存扣减优化 │ Redis预扣(Lua原子操作) 异步同步到DB │ │ │ → 防超卖 高性能 │ ├──────────────────┼───────────────────────────────────────────────┤ │ 批量操作 │ 批量写入、批量查询减少DB交互 │ ├──────────────────┼───────────────────────────────────────────────┤ │ 限流降级 │ 大促时: 关闭非核心功能, 保障下单链路 │ └──────────────────┴───────────────────────────────────────────────┘8.2 分库分表方案分库分表策略: 水平分库: 按user_id取模 db_0: user_id % 4 0 db_1: user_id % 4 1 db_2: user_id % 4 2 db_3: user_id % 4 3 水平分表: 按月份分表(每库12张表/年) t_order_202601, t_order_202602, ..., t_order_202612 分片键: user_id create_time → 同一用户的订单在同一库 → 方便用户维度查询 → 按月分表 → 避免单表过大 → 方便历史数据归档 跨库查询问题: → 商家维度查询(store_id): 用ES做CQRS查询(订单数据同步到ES) → 全局统计: 用数仓做离线统计 → 订单详情: 必须用order_id查询 → order_id包含路由信息 // order_id 编码方案 (Snowflake变体) | 1bit | 41bit(时间戳) | 5bit(库) | 5bit(表) | 12bit(序列) | → 从order_id可直接解析出库号和表号 → 精准路由九、能力复用度量9.1 业务中台效果指标业务中台建设效果度量: ┌────────────────┬───────────────────┬────────────────────────────┐ │ 指标 │ 衡量方式 │ 目标值 │ ├────────────────┼───────────────────┼────────────────────────────┤ │ 接入业务数 │ 调用中台API的 │ 用户中心 ≥ 5个业务线 │ │ │ 业务系统数量 │ 订单中心 ≥ 3个业务线 │ │ │ │ 支付中心 ≥ 3个业务线 │ ├────────────────┼───────────────────┼────────────────────────────┤ │ 接口复用率 │ 被多个业务调用的 │ ≥ 60%接口被2业务线调用 │ │ │ API占比 │ │ ├────────────────┼───────────────────┼────────────────────────────┤ │ 新业务上线周期 │ 从立项到上线 │ 基础能力接入 ≤ 2周 │ │ │ │ 差异化开发 ≤ 4周 │ ├────────────────┼───────────────────┼────────────────────────────┤ │ 接口SLA │ 可用性 响应时间 │ 99.95% P99 200ms │ ├────────────────┼───────────────────┼────────────────────────────┤ │ 故障隔离率 │ 单中心故障不 │ ≥ 80%故障可隔离 │ │ │ 影响其他中心 │ │ └────────────────┴───────────────────┴────────────────────────────┘要点回顾订单中心核心订单创建全链路(幂等控制→商品校验→库存预扣→价格计算→写入数据)、状态机驱动生命周期、超时自动处理库存方案下单预扣(Redis Lua原子操作) 支付实扣(DB) 超时释放 风控防恶意占库存价格引擎原价→优惠计算→优惠分摊(按比例兜底取整)→运费→积分抵扣→实付金额支付中心渠道适配器模式统一接口、支付路由策略、回调幂等处理(验签Redis幂等乐观锁)退款对账退款全流程(申请→审核→执行→回调)、T1日终对账(平账/差错/挂账)分布式事务RocketMQ事务消息保证订单库存最终一致性消费端幂等保证高可用分库分表(user_id分库按月分表)、读写分离、热点缓存、异步化、限流降级下一篇预告下一篇将进入落地实践篇全景解析中台技术选型决策框架——开源 vs 自研的判断标准、各层技术选型对比、总拥有成本(TCO)分析帮助团队做出最适合自己的选择。
网站建设高端定制企业官网