一、项目背景与需求分析
在电商行业,优惠券是提升用户转化率、促进复购的核心营销工具。当系统需要支撑亿级流量时,需解决高并发、分布式事务、数据一致性等核心挑战。
关键需求点:
- 高并发支持:秒杀场景下需支撑每秒数万级请求
- 实时性要求:优惠券状态变更需毫秒级同步
- 分布式事务:涉及库存、订单、支付等多系统协同
- 精准营销:支持用户画像、AB测试等精细化运营
典型业务场景示例:
// 用户领取优惠券伪代码public boolean acquireCoupon(Long userId, Long couponId) {// 1. 检查用户资格(黑名单、频次限制)// 2. 验证优惠券库存(分布式锁)// 3. 创建领取记录(事务保证)// 4. 推送领取成功消息}
二、系统架构设计
1. 分层架构设计
采用经典分层架构:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐│ API层 │ → │ 服务层 │ → │ 数据层 │└─────────────┘ └─────────────┘ └─────────────┘↑ ↑ ↑┌─────────────────────────────────────────────┐│ 缓存层(Redis集群) │└─────────────────────────────────────────────┘
关键设计决策:
- API层:采用Spring Cloud Gateway实现限流、熔断
- 服务层:按业务拆分(领券服务、用券服务、核销服务等)
- 数据层:MySQL分库分表(按用户ID哈希分16库)
2. 核心数据模型
CREATE TABLE coupon_template (id BIGINT PRIMARY KEY,name VARCHAR(100) NOT NULL,type TINYINT COMMENT '1-折扣 2-满减 3-现金',discount DECIMAL(10,2),threshold DECIMAL(10,2),total_count INT,remain_count INT,start_time DATETIME,end_time DATETIME,status TINYINT COMMENT '0-未开始 1-进行中 2-已结束');CREATE TABLE coupon_record (id BIGINT PRIMARY KEY,user_id BIGINT NOT NULL,template_id BIGINT NOT NULL,status TINYINT COMMENT '0-未使用 1-已使用 2-已过期',acquire_time DATETIME,use_time DATETIME,order_id BIGINT);
三、核心模块实现
1. 高并发领券实现
解决方案:
-
Redis原子操作:使用DECR命令实现库存扣减
// Redis库存扣减示例public boolean decrStock(Long couponId) {String key = "coupon
" + couponId;Long result = redisTemplate.opsForValue().decrement(key);if (result == null || result < 0) {redisTemplate.opsForValue().increment(key); // 回滚return false;}return true;}
-
异步消息队列:领券成功后通过RocketMQ异步处理后续逻辑
- 令牌桶限流:Guava RateLimiter控制每秒请求量
2. 分布式事务处理
采用TCC模式实现跨系统事务:
@Transactionalpublic boolean commitCouponUse(Long recordId, Long orderId) {// Try阶段couponRecordDao.updateStatusToUsing(recordId);try {// Confirm阶段orderService.applyCoupon(orderId, recordId);couponRecordDao.updateStatusToUsed(recordId);} catch (Exception e) {// Cancel阶段couponRecordDao.updateStatusToUnused(recordId);throw e;}}
3. 优惠券核销优化
性能优化策略:
- 本地缓存:使用Caffeine缓存用户可用券列表
- 批量查询:一次查询获取订单所有可用券
- 规则引擎:Drools实现复杂核销规则
四、性能优化实践
1. 数据库优化
- 分库分表:按用户ID哈希分16库,单表数据量控制在500万以内
- 读写分离:主库写,从库读(一主三从)
- 索引优化:组合索引覆盖查询字段
2. 缓存策略
多级缓存架构:
本地缓存(Caffeine) → Redis集群 → 分布式缓存(如果需要)
缓存更新模式:
- 写后清除:更新数据库后立即清除缓存
- 异步刷新:通过消息队列延迟刷新
3. 监控体系
关键监控指标:
1. QPS/TPS:系统吞吐量2. 错误率:5xx请求比例3. 响应时间:P99/P95指标4. 缓存命中率:Redis命中率
五、部署与运维方案
1. 容器化部署
采用Kubernetes集群部署:
# deployment示例apiVersion: apps/v1kind: Deploymentmetadata:name: coupon-servicespec:replicas: 8selector:matchLabels:app: coupon-servicetemplate:metadata:labels:app: coupon-servicespec:containers:- name: coupon-serviceimage: coupon-service:v1.0.0resources:limits:cpu: "1"memory: "2Gi"
2. 弹性伸缩策略
基于CPU和QPS的自动伸缩:
- CPU使用率 > 70%:扩容2个Pod- QPS > 5000:扩容1个Pod- 响应时间 > 500ms:触发告警
六、实战经验总结
- 渐进式压力测试:从100QPS开始逐步加压,定位性能瓶颈
- 熔断降级策略:Hystrix实现服务降级,避免雪崩效应
- 数据一致性保障:最终一致性+补偿机制
- 监控告警体系:Prometheus+Grafana可视化监控
典型问题解决方案:
- 超卖问题:Redis+数据库双重校验
- 缓存穿透:空值缓存+布隆过滤器
- 消息堆积:增加Consumer数量+批量消费
通过以上架构设计和优化策略,系统成功支撑了双十一期间单日数亿次优惠券操作,P99响应时间控制在80ms以内。实际开发中需根据具体业务场景调整技术方案,建议采用灰度发布逐步验证系统稳定性。