目录
一、先搞懂:电商高并发的核心场景
高并发主要集中在3个核心环节:
- 秒杀/促销(瞬间海量请求,比如618开抢);
- 商品详情页(大量用户同时浏览);
- 订单/支付(高并发创建订单、扣库存)。
二、核心解决方案(极简+实战)
1. 缓存兜底(最基础、性价比最高)
核心思路:把高频访问的数据(商品详情、库存数)放到Redis里,避免每次都查数据库,减轻DB压力。
实战例子:
- 商品详情页:用户访问时先查Redis,Redis没有再查DB,查到后回写Redis(设置过期时间,比如10分钟);
- 库存数:扣库存前先查Redis中的库存,扣减时先更Redis,再异步同步到DB(秒杀场景)。
核心代码(库存缓存):
// 查库存(先查缓存)
public int getStock(Long skuId) {
String key = "stock:" + skuId;
// 1. 查Redis
String stockStr = redisTemplate.opsForValue().get(key);
if (stockStr != null) {
return Integer.parseInt(stockStr);
}
// 2. Redis没有,查DB
int stock = stockMapper.selectStockBySkuId(skuId);
// 3. 回写Redis(过期时间10分钟)
redisTemplate.opsForValue().set(key, String.valueOf(stock), 10, TimeUnit.MINUTES);
return stock;
}
2. 限流熔断(防系统被打垮)
核心思路:限制每秒请求数,超出的请求直接拒绝;服务异常时熔断,避免雪崩。
常用工具:Guava RateLimiter(本地限流)、Sentinel/Spring Cloud Gateway(分布式限流)。
实战例子(秒杀接口限流):
// 初始化限流器:每秒最多处理1000个请求
private final RateLimiter rateLimiter = RateLimiter.create(1000.0);
@PostMapping("/seckill")
public String seckill(Long skuId) {
// 1. 尝试获取令牌,获取不到直接返回
if (!rateLimiter.tryAcquire()) {
return "请求太火爆,请稍后再试";
}
// 2. 执行业务逻辑
seckillService.doSeckill(skuId);
return "秒杀成功";
}
3. 分布式锁(防超卖/重复下单)
核心思路:用Redis/ZooKeeper做分布式锁,保证同一商品的库存扣减只有一个线程执行。
实战例子(扣库存防超卖):
public boolean deductStock(Long skuId) {
String lockKey = "lock:stock:" + skuId;
// 1. 获取分布式锁(过期时间30秒,防死锁)
Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "LOCK", 30, TimeUnit.SECONDS);
if (Boolean.FALSE.equals(locked)) {
return false; // 有其他线程在扣库存,直接返回
}
try {
// 2. 查库存(DB)
int stock = stockMapper.selectStockBySkuId(skuId);
if (stock <= 0) {
return false; // 库存不足
}
// 3. 扣库存
stockMapper.deductStock(skuId);
// 4. 更新Redis库存
redisTemplate.opsForValue().decrement("stock:" + skuId);
return true;
} finally {
// 5. 释放锁
redisTemplate.delete(lockKey);
}
}
4. 异步处理(削峰填谷)
核心思路:把非实时的操作(比如生成订单、发送短信)放到MQ(RocketMQ/Kafka)里,异步处理,快速返回请求。
实战例子(创建订单):
@PostMapping("/createOrder")
public String createOrder(OrderDTO orderDTO) {
// 1. 生成订单ID
String orderId = UUID.randomUUID().toString();
orderDTO.setOrderId(orderId);
// 2. 发送MQ消息,异步创建订单
rocketMQTemplate.send("create-order-topic", MessageBuilder.withPayload(orderDTO).build());
// 3. 快速返回,不用等订单创建完成
return "订单提交成功,订单号:" + orderId;
}
// MQ消费者(异步处理订单)
@Service
@RocketMQMessageListener(topic = "create-order-topic", consumerGroup = "order-group")
public class OrderConsumer implements RocketMQListener<OrderDTO> {
@Override
public void onMessage(OrderDTO orderDTO) {
// 异步创建订单、扣库存、记录日志
orderService.createOrder(orderDTO);
}
}
5. 数据库优化(底层保障)
核心思路:减少DB压力,提升查询/写入效率。
- 分库分表:订单表按用户ID分表(比如分100张表),避免单表数据量过大;
- 索引优化:给商品ID、订单号等高频查询字段加索引;
- 读写分离:读请求走从库,写请求走主库。
三、核心方案总结
- 缓存兜底:Redis缓存高频数据(商品、库存),减少DB访问;
- 限流熔断:限制请求数,防系统过载,常用Sentinel/RateLimiter;
- 分布式锁:Redis/ZK保证库存扣减、订单创建的原子性,防超卖;
- 异步处理:MQ削峰,异步处理订单、短信等非实时操作;
- DB优化:分库分表、读写分离、索引优化,夯实底层。
关键点回顾
- 电商高并发核心是“减压力、防超卖、削峰值”;
- 优先用缓存+限流快速降压力,分布式锁解决数据一致性,MQ削峰填谷;
- 所有方案最终要落地到“保护数据库”,避免DB成为瓶颈。
浙公网安备 33010602011771号