网站空间买什么的好,链接点开网页表白的网站怎么做的,游戏币交易平台代理,精美的网页分布式锁是我们在分布式场景中经常用到的一种技术#xff0c;在后端面试中也是出镜率很高#xff0c;那么我们设计分布式锁的时候应该从那几方面去考虑呢
实现分布式锁需要考虑的点
设置超时时间
设置超时时间的目的是为了避免这个场景#xff1a;进程A拿了锁#xff0c…分布式锁是我们在分布式场景中经常用到的一种技术在后端面试中也是出镜率很高那么我们设计分布式锁的时候应该从那几方面去考虑呢
实现分布式锁需要考虑的点
设置超时时间
设置超时时间的目的是为了避免这个场景进程A拿了锁但是在持有锁期间自己因为某些异常挂掉了这样进程A就永远不会释放掉这个锁了。如果没有设置超时时间的话这个锁就会死锁所以会需要设置一个超时时间来保证当锁的持有者无法释放锁的时候锁不会成为死锁。
设置守护线程
设置守护线程的目的是为了避免这个场景进程A拿了锁也设置了超时时间30s但是因为某些业务的原因进程A确实需要持有锁超过30s那么这个时候如果不加任何干预的话30s后锁自动释放肯定是不符合预期的。
有些同学可能就会问了那我不是把超时时间设置长一点就好吗但是一是超时时间设置长了是会有副作用的那就是锁持有者无法释放锁时锁自动持有的时间会变长二是即使设置的再长也是有个限制的无法完全保证不会发生正常使用的锁被错误的自动释放掉。
所以我们需要在持有锁的这个进程中额外增加一个线程具体做的事情就是当持有锁的时间超过锁过期时间的一半时自动对超时时间进行一个续期这样当进程存在的时候就会一直对超时时间进行续期不会被意外的自动释放如果进程挂掉的话则不会进行续期超时后锁会被自动释放也不会产生死锁。
Redis实现分布式锁主要要注意的地方
使用SETNX实现排他性锁SETNX意为set if not exist即如果这个锁已经被持有了则无法再次申请使用超时限制特性来避免死锁释放锁的时候需要进行检查来避免误释放别的进程的锁添加key的时候使用uuid生成一个identifier作为key的value随key一同写入redis释放的时候使用get命令获取到锁的value的时候检查是不是之前存的那个identifier如果不是的话就说明锁已经释放了
tooz实现基于redis的分布式锁的实现方法
获取到一个锁的实例以后如果acquire成功则将acquired置为True
任意一个锁的实例想要release锁的话先判断acquired是否为True如果为True才允许释放如果为False直接抛出异常“不能释放没有获取的锁”以此避免错误释放
超时时间过一半以后实例会自动延长超时时间到原本设置的超时时间避免因为超时时间的设置把原本需要很长时间处理的任务的锁错误的释放掉了
使用setnx和expire的问题setnx和expire是两条指令而不是原子指令。
解决办法使用set扩展参数替代set key value ex 5 nx