"3、2、1,开抢!"小王的手机屏幕刚显示秒杀开始,点击购买的瞬间系统却卡住了,刷新后,价值999元的手机已经显示"已售罄",这不是运气问题,而是典型的高并发场景下数据竞争导致的悲剧——同一时刻可能有上万人同时点击购买,系统却无法准确判断库存。
这种场景在电商大促、票务系统、金融交易中比比皆是,如何保证在分布式环境下,关键操作像单机程序一样有序执行?这就是分布式锁要解决的核心问题。
分布式锁本质上是一个在多个独立进程或服务器之间协调共享资源访问的机制,一个好的分布式锁需要满足四个基本要求:
SETNX lock_key unique_value EXPIRE lock_key 10
这是最原始的实现方式,但存在致命缺陷——SETNX和EXPIRE是两个独立操作,不是原子的,如果在SETNX后客户端崩溃,锁将永远不会释放。
Redis 2.6.12后,SET命令支持NX和EX参数,解决了原子性问题:
SET lock_key unique_value NX EX 10
这个版本已经可以满足基本需求,但仍有优化空间,比如锁过期时间设置多少合适?设置太短可能导致业务未完成锁就释放;设置太长又会影响系统响应。
Redis作者Antirez提出了Redlock算法,核心思想是:
虽然Redlock提高了可靠性,但也带来了性能开销和实现复杂度,对于大多数业务场景,单节点Redis锁已经足够。
value应该是全局唯一的,通常使用UUID或客户端ID+时间戳,这能防止误删其他客户端的锁:
String value = UUID.randomUUID().toString();
对于执行时间不确定的长任务,可以实现锁续期机制,Java中可以使用Redisson库的watchDog:
RLock lock = redisson.getLock("myLock"); lock.lock(); // 默认30秒过期,看门狗会自动续期 try { // 业务逻辑 } finally { lock.unlock(); }
同一线程多次获取同一把锁时应该允许,这称为锁的可重入性,Redisson等成熟客户端已经内置支持。
根据业务需求选择阻塞等待锁还是快速失败:
// 尝试获取锁,最多等待100秒,上锁后10秒自动解锁 boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); // 立即返回获取结果 boolean res = lock.tryLock();
现象:锁自动释放时业务逻辑还在执行,导致数据不一致。
解决方案:
现象:主从切换时可能出现多个客户端同时持有锁。
解决方案:
注意:即使使用Redis,在AOF未刷盘或RDB未持久化时重启仍可能丢失锁信息,对强一致性要求的场景,需要考虑ZooKeeper等方案。
@RestController public class SeckillController { @Autowired private StringRedisTemplate redisTemplate; @PostMapping("/seckill") public String seckill(@RequestParam String productId) { String lockKey = "lock:" + productId; String clientId = UUID.randomUUID().toString(); try { // 尝试加锁 Boolean result = redisTemplate.opsForValue() .setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS); if (!Boolean.TRUE.equals(result)) { return "系统繁忙,请重试"; } // 业务逻辑 int stock = Integer.parseInt( redisTemplate.opsForValue().get("stock:" + productId)); if (stock > 0) { redisTemplate.opsForValue() .decrement("stock:" + productId); return "秒杀成功"; } else { return "已售罄"; } } finally { // 确保只释放自己的锁 if (clientId.equals(redisTemplate.opsForValue().get(lockKey))) { redisTemplate.delete(lockKey); } } } }
Redis分布式锁是处理并发问题的利器,但绝非银弹,2025年的今天,随着Redis7.0对脚本和事务的增强,以及Redisson等客户端库的完善,开发者拥有了更多武器来应对高并发挑战,技术方案永远服务于业务需求,在简单与复杂之间找到平衡点,才是架构设计的艺术所在。
本文由 声玲玲 于2025-08-07发表在【云服务器提供商】,文中图片由(声玲玲)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/561767.html
发表评论