开发说重复提交的问题修好了,锁从 20 秒超时改成 60 秒阻塞锁。 我当时觉得,这事儿稳了。加锁嘛,谁抢不到就排队等,多等一会儿总比写重了好。 然后我去翻… · @sirHe12 · TwKit
@sirHe12
开发说重复提交的问题修好了,锁从 20 秒超时改成 60 秒阻塞锁。 我当时觉得,这事儿稳了。加锁嘛,谁抢不到就排队等,多等一会儿总比写重了好。 然后我去翻日志。 154 条请求,我按时间一条条排开看。每一条的顺序都是:先把旧数据删了,隔 6 到 7 秒,然后才去拿锁。 删除永远在拿锁前面。注定要失败的那些请求,压根没碰到锁,就把别人的数据删了。 所以那把锁从头到尾没争用过——翻了 5 天监控,取锁失败的记录全是 0。 我一开始以为是环境问题,觉得 5 天总该撞上过一次争用。查完才知道,那 5 天里所有并发都卡在锁外面就被拦下了,锁连竞争的机会都没有。开发在现网把 20 秒改成 60 秒,测不出任何差别,因为差别压根不在超时时间上。 问题不在锁是什么实现,在锁加在了哪一步。 真正要命的是这个窗口有多宽:删除到取锁之间隔了 6 到 7 秒。两个人手快点,前后差 5 秒各点一次,就打中了。 顺带留个坑给以后:这类问题在监控上看不出来。「取锁失败 0 次」本来是健康信号,恰恰说明锁在关键路径之外。 你们做代码审查时,用什么静态检查工具能抓出这种把写操作漏在加锁前面的问题?
曝光 14 · 评论 0 · 点赞 2 · 书签 0
查看原帖