返回

压测异常排查:拨开迷雾,找出Redisson锁失效的幕后黑手

后端

异常现场回顾

7 月 7 日,我们对小驴班级推送视频任务功能进行压测。压测过程中,我们发现有一部分接口请求失败。小驴端上报的推送失败异常如下:

java.lang.RuntimeException: 服务器异常
    at com.netease.edu.ilearning.content.push.service.PushAppService.getAccessToken(PushAppService.java:144)
    at com.netease.edu.ilearning.content.push.service.PushAppService.doVideoPush(PushAppService.java:86)
    at com.netease.edu.ilearning.content.push.service.VideoPushService.push(VideoPushService.java:62)

这个异常日志是小驴端收到的。异常内容是网校网关返回的异常页面,如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

</head>
<body>
<h1>RedissonLock Release lock error</h1>
<p>释放锁失败,服务重启,会导致Redisson锁失效。</p>
</body>
</html>

问题分析

从异常日志中,我们可以看出问题出在Redisson锁上。Redisson锁是一种分布式锁,用于保证在并发场景下,只有一个线程能够访问共享资源。在我们的案例中,Redisson锁用于控制对数据库的并发访问。

我们怀疑Redisson锁失效的原因是服务重启导致的。服务重启时,Redisson锁会自动释放,这会导致其他线程能够访问共享资源,从而引发异常。

问题解决

为了解决这个问题,我们采取了以下措施:

  1. 首先,我们修改了Redisson锁的配置,将锁的过期时间设置为30分钟。这样,即使服务重启,Redisson锁也不会立即失效,而是会等待30分钟后再释放。
  2. 其次,我们对服务进行了优化,减少了服务重启的频率。
  3. 最后,我们对代码进行了修改,在使用Redisson锁时,添加了锁的重试机制。这样,即使Redisson锁失效了,我们的代码也能自动重试,直到获取到锁为止。

最佳实践

通过这次压测异常排查,我们总结了以下最佳实践:

  1. 在使用Redisson锁时,应该设置合理的锁过期时间,避免服务重启时锁失效导致的问题。
  2. 应该尽量减少服务重启的频率,以避免Redisson锁失效的可能性。
  3. 在使用Redisson锁时,应该添加锁的重试机制,以保证即使Redisson锁失效,我们的代码也能自动重试,直到获取到锁为止。

结语

希望这篇技术指南能帮助您在面临类似问题时快速定位和解决问题,从而避免不必要的性能瓶颈和服务中断。