文档首页> 上云指南> 优惠券系统的设计与配置

优惠券系统的设计与配置

发布时间:2026-04-20 21:23        更新时间:2026-04-21 20:54
发出去的券收不回来,是优惠券系统最常见的事故形态。发放、核销、对账这三件事在设计阶段没想清楚,后期补漏洞的代价远高于前期设计。 一、防超发是底线 库存扣减必须原子化。最朴素的做法是数据库条件更新: UPDATE coupon_stock SET remain = remain - 1 WHERE batch_id = 1001 AND remain > 0; 影响行数为 0 就表示已发完,接口直接返回"已领完"。用 Redis 的 DECR 原子递减也可以,但要防止减成负数后再回补,回补逻辑写错照样超发。领取接口另加用户维度去重:同一用户对同一批次只能领一次,用唯一索引兜底,比在代码里先查再插可靠得多。 二、核销走状态机 一张券的状态要明确:未使用、已锁定、已核销、已过期。核销分两步,先锁定再确认,两步都放在数据库事务里。重复核销用状态机挡住,当前状态不是"未使用"就直接拒绝。这样即使接口被重复调用、被并发刷,数据也不会乱。锁定的券超时未确认,要自动回滚到未使用状态,避免库存被占死。 三、流水与对账 发券、领券、核销每个动作都记操作流水,字段至少包括批次号、用户 ID、动作类型、时间戳。每天凌晨跑一次对账脚本,核对三个数:应发总量、实际领取量、已核销加未过期剩余,三者必须相等。对不上就按流水逐笔找差异,不要直接手改库存表,把差异原因查清楚再说。 四、部署与压测 压力集中在活动开抢的一两分钟,其余时间很闲。机器按峰值选型:小型活动用高防云服务器 S4 即可,带数据库或内存吃紧的升到 S4-8G,数据库与 Web 服务分开部署。上线前用 wrk 之类的压测工具模拟并发领取,把各种极端时序都跑一遍,确认不超发再对外开活动。 优惠券系统的代码量不大,难在把钱和库存算准。每次活动结束后把账再核一遍,对账脚本的结果同步到值班群,异常当天处理。