if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
# 调用 EVAL 传入 key 与唯一值
任务超时后锁被自动释放,另一个任务拿到锁,前一个任务收尾时把新锁删掉了。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,解锁时没有校验持有者,直接删除键,导致误删其他实例的锁。
「Redis 分布式锁」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。
处理上按这个顺序:value 写入唯一标识;用 lua 脚本比对后再删除;给锁设置合理的过期与续期。
改完只确认一件事:并发任务执行时不再互相删锁,重复执行问题消失。