mall-项目redis三剑客
一、分布式锁
文件 说明
mall-common/.../lock/RedisDistributedLock.java 核心锁工具,SET NX PX 加锁 + Lua 脚本原子解锁
mall-common/.../lock/DistributedLock.java @DistributedLock 注解
mall-common/.../lock/DistributedLockAspect.java AOP 切面,支持 SPEL 动态 key
mall-common/.../lock/LockConfig.java 配置类,注入 StringRedisTemplate
使用示例 — 在秒杀/下单方法上加注解:
@DistributedLock(key = "'stock:lock:' + #skuId", waitMs = 3000)
public void deductStock(Long skuId, Integer quantity) {
// 业务逻辑
}
或编程式调用:
redisDistributedLock.executeWithinLock("stock:lock:" + skuId, 5000, () -> {
// 临界区代码
return null;
});
二、限流
文件 说明
mall-common/.../ratelimit/RateLimit.java @RateLimit 注解
mall-common/.../ratelimit/RateLimitAspect.java AOP 切面,Redis Lua 脚本(INCR + PEXPIRE 原子执行)
使用示例 — 在 Controller 方法上加注解:
@RateLimit(key = "'rate:login:' + #username", count = 5, time = 1, timeUnit = RateLimit.TimeUnit.MINUTES)
@PostMapping("/sso/login")
public CommonResult login(String username, String password) {
// 每分钟同一用户名最多登录5次
}
三、ZSet 延时队列(订单超时取消)
文件 说明
mall-portal/.../component/RedisOrderDelayQueue.java ZSet 延迟队列,CommandLineRunner 启动后每1秒轮询
mall-portal/.../component/SpringContextHolder.java Spring 上下文持有器,供非 Bean 类获取 Bean
RedisService.java + RedisServiceImpl.java 已新增 zAdd / zRemove / zRangeByScore / zScore 四个方法
使用方式 — 在 generateOrder() 之后,用 ZSet 替代 RabbitMQ 延迟消息:
// 替换原有的 sendDelayMessageCancelOrder(order.getId())
redisOrderDelayQueue.add(order.getId(), 1800); // 30分钟后执行
取消时清除延迟任务(在 paySuccess() / cancelOrder() 中调用):
redisOrderDelayQueue.remove(orderId);
Redis Key 结构:
mall:delay:order:cancel → ZSet { orderId: score(执行时间戳) }
mall:delay:order:cancel:lock → 分布式锁防止并发轮询
轮询线程每1秒扫描一次,取出 score <= now 的订单执行 cancelOrder(),无需 RabbitMQ 即可实现超时自动取消,且不使用 @Scheduled 影响现有定时任务。