4人参与 • 2025-12-09 • Redis
我们是做物联网设备的公司,设备初始化会向设备发送api接口下发agora license,当时当时一个环境的全部agora设备都下发出现了问题,具体表现为:
多个设备出故障频繁注册+redisson.lock() 强制等待锁释放造成线程池资源耗尽
以设备20252025为例,当下发设备license时,第一次会创建一个20252025的锁,但是这个设备也有其他在线程池的进程进行下发,因为使用的是lock,是无限期等待锁,所以线程池资源来利用不起来,导致触发拒绝策略
redisson创建分布式锁的lua脚本是
-- lua 脚本(原子执行)
if (redis.call('exists', keys[1]) == 0) then
redis.call('hset', keys[1], argv[2], 1);
redis.call('pexpire', keys[1], argv[1]);
return nil;
end;
if (redis.call('hexists', keys[1], argv[2]) == 1) then
redis.call('hincrby', keys[1], argv[2], 1);
redis.call('pexpire', keys[1], argv[1]);
return nil;
end;
return redis.call('pttl', keys[1]);可以看到value值(value)的结构: 锁的值存储的是一个字符串(string),内容为锁 持有者的唯一标识符和可重入计数,格式为: :: ·uuid:redisson客户端实例的唯一标识符(每个客户端启动时生成) ·threadid:持有锁的线程id(支持可重入锁 同一线程多次加锁) ·count:锁的可重入次数(初始为1,每次重入加1,释放时减1)
uuid为啥不变 猜测是服务pod没被杀 自己拉起来时候 这个客户端id不变导致的
在某一次的k8s滚动更新时,可能因为未在对应时间内执行完线程池任务(如最后30s等待关闭时间内,虽然没有新任务进,但是进程1在最后1s释放了锁,进程2在此时拿到了锁),导致finally代码块的解锁逻辑并未执行,导致该锁一直被占用,新pod启动后又给redlock续期导致该锁一直没有被释放
因为这两个原因导致线上出现问题
到此这篇关于redisson使用lock导致死锁问题解决的文章就介绍到这了,更多相关redisson使用lock导致死锁内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论