直播电商促销的核心挑战在于应对瞬间流量高峰。我们采用分层架构确保系统稳定:
使用Nginx作为反向代理,配置如下:
http {
upstream backend {
server 192.168.1.101:8080 weight=5;
server 192.168.1.102:8080 weight=5;
keepalive 32;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
采用微服务架构,将商品服务、订单服务、库存服务解耦。每个服务独立部署,通过RESTful API通信。
使用Redis集群存储库存数据,MySQL存储订单和用户数据。Redis主从配置确保数据可靠性。
活动开始前5分钟,将商品库存加载到Redis:
// Java示例代码
public void preheatStock(Long productId, Integer stock) {
String key = "stock:" + productId;
redisTemplate.opsForValue().set(key, stock.toString());
// 设置过期时间为活动结束后2小时
redisTemplate.expire(key, 7200, TimeUnit.SECONDS);
}
使用Redis的DECR命令确保原子性:
public boolean deductStock(Long productId) {
String key = "stock:" + productId;
Long remaining = redisTemplate.opsForValue().decrement(key);
if (remaining != null && remaining >= 0) {
// 扣减成功,异步同步到数据库
asyncUpdateDBStock(productId);
return true;
} else {
// 库存不足,恢复Redis库存
redisTemplate.opsForValue().increment(key);
return false;
}
}
使用Spring Cloud Gateway配置限流:
spring:
cloud:
gateway:
routes:
- id: seckill_route
uri: lb://seckill-service
predicates:
- Path=/api/seckill/
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1000
redis-rate-limiter.burstCapacity: 2000
key-resolver: "{@userKeyResolver}"
使用Resilience4j配置熔断器:

resilience4j.circuitbreaker:
instances:
seckillService:
slidingWindowSize: 100
failureRateThreshold: 50
waitDurationInOpenState: 10s
permittedNumberOfCallsInHalfOpenState: 10
使用RocketMQ处理订单创建请求:
// 生产者配置
@Configuration
public class RocketMQConfig {
@Bean
public DefaultMQProducer producer() {
DefaultMQProducer producer = new DefaultMQProducer("seckill_producer_group");
producer.setNamesrvAddr("192.168.1.100:9876");
producer.setRetryTimesWhenSendFailed(3);
return producer;
}
}
// 发送订单消息
public void sendOrderMessage(OrderDTO order) {
Message msg = new Message("seckill_order_topic",
JSON.toJSONString(order).getBytes());
SendResult result = producer.send(msg);
}
订单消费者处理逻辑:
@Component
@RocketMQMessageListener(
topic = "seckill_order_topic",
consumerGroup = "order_consumer_group"
)
public class OrderConsumer implements RocketMQListener {
@Override
public void onMessage(MessageExt message) {
String body = new String(message.getBody());
OrderDTO order = JSON.parseObject(body, OrderDTO.class);
// 1. 检查库存(二次验证)
// 2. 创建订单记录
// 3. 扣减数据库库存
// 4. 发送订单创建成功通知
}
}
在提交订单前必须通过验证码:
// 生成验证码
public String generateCaptcha(String userId) {
String captcha = RandomStringUtils.randomNumeric(6);
String key = "captcha:" + userId;
redisTemplate.opsForValue().set(key, captcha, 300, TimeUnit.SECONDS);
return captcha;
}
// 验证验证码
public boolean verifyCaptcha(String userId, String inputCaptcha) {
String key = "captcha:" + userId;
String storedCaptcha = redisTemplate.opsForValue().get(key);
return inputCaptcha != null && inputCaptcha.equals(storedCaptcha);
}
使用Redis记录用户购买次数:
public boolean checkUserPurchaseLimit(Long userId, Long productId) {
String key = "user_limit:" + productId + ":" + userId;
Long count = redisTemplate.opsForValue().increment(key);
if (count == 1) {
// 首次设置,过期时间设为活动持续时间
redisTemplate.expire(key, 3600, TimeUnit.SECONDS);
}
return count <= 1; // 每个用户限购1件
}
在application.yml中配置指标暴露:
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
export:
prometheus:
enabled: true
groups:
- name: seckill_alerts
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
for: 2m
labels:
severity: critical
annotations:
summary: "高错误率告警"
- alert: LowStockWarning
expr: redis_stock{product="seckill_item"} < 100
for: 1m
labels:
severity: warning
annotations:
summary: "库存不足告警"
使用JMeter进行压力测试:
// JMeter测试计划结构
1. 线程组:设置并发用户数=5000,持续时间=10分钟
2. HTTP请求:POST /api/seckill/submit
3. 请求参数:productId=1001, userId=${__Random(1,100000)}
4. 断言:响应状态码=200,响应包含"success"
5. 聚合报告:查看TPS、响应时间、错误率
当Redis与数据库库存不一致时:
// 库存核对脚本
public void checkStockConsistency(Long productId) {
// 从Redis获取库存
String redisStock = redisTemplate.opsForValue()
.get("stock:" + productId);
// 从数据库获取库存
Integer dbStock = productMapper.selectStock(productId);
if (!String.valueOf(dbStock).equals(redisStock)) {
// 以数据库为准,修复Redis库存
redisTemplate.opsForValue()
.set("stock:" + productId, dbStock.toString());
log.warn("库存不一致已修复,productId: {}", productId);
}
}
按照上述步骤实施,你可以构建一个能够支撑万人同时抢购的直播电商促销系统。每个环节都经过实战检验,关键配置可直接复制使用。在实际部署时,请根据你的业务规模调整参数,特别是限流阈值和服务器配置。
易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。
Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图