关于springboot2整合lettuce启动卡住问题的解决方法

作者:人淡如菊 时间:2022-08-24 09:29:16 

前言

EasyCache升级兼容 Springboot2,有个业务系统启动总是会卡住,最后抛出超时异常,如下:


java.util.concurrent.TimeoutException: null

at java.util.concurrent.FutureTask.get(FutureTask.java:205)

.....

springboot 版本是 2.2.x,springCloudVersion 版本是 2.2.x, lettuce版本是5.2.x,如果使用jedis客户端没有,所以问题一定是出在lettuce。

分析原因

如果是线上发生这个问题会使用 jstack 查看线程的情况,在本地idea调试就更加方便了,查看线程发现lettuce的线程被Blocked,dump出的部分信息如下:

"lettuce-kqueueEventLoop-7-1@14257" daemon prio=5 tid=0x4c nid=NA waiting for monitor entry

  java.lang.Thread.State: BLOCKED

 waiting for main@1 to release lock on <0x38a5> (a java.util.concurrent.ConcurrentHashMap)

  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:208)

  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)

  ....

看第一行的报错是在获取Bean的时候阻塞了,说明有地方获取Bean的时候没有释放锁。在这地方打断点发现是 spring-cloud-sleuth 的 SamplerAutoConfiguration获取bean的时候有锁没有释放。源代码如下


protected static class RefreshScopedSamplerConfiguration {
public Sampler defaultTraceSampler(SamplerProperties config) {
return samplerFromProps(config);
}
}

@RefreshScope 获取代理类的时候如果是@PostConstruct的方法,bean是加载不到,所以导致一直没有释放锁。所以猜想,容器还没有启动完成的时候,有地方调用了lettuce的Bean,导致循环依赖。

坑的复现及解决办法

运行下面这段代码,错误就出现了,和业务系统出现的问题一模一样,也验证了上面的猜想。解决办法是在容器启动之后在调用init方法。(实测使用InitializingBean时也会出现该问题)


public class SpringDataTestService {
   private StringRedisTemplate stringRedisTemplate;
   //@EventListener(MainContextRefreshedEvent.class)
   public void init() {
       String s = stringRedisTemplate.opsForValue().get("gateway:ab-test:config");
       System.out.println(s);
   }
}

来源:https://www.panaihua.com/lettuce-blocked/

标签:springboot2,整合,lettuce
0
投稿

猜你喜欢

  • Java函数式编程(十二):监控文件修改

    2022-08-11 10:21:01
  • Java读取、写入文件如何解决乱码问题

    2023-08-26 11:16:00
  • 实例化JFileChooser对象报空指针异常问题的解决办法

    2023-10-05 11:36:18
  • Android App中使用ViewPager+Fragment实现滑动切换效果

    2023-01-12 19:51:50
  • Flutter状态管理Provider示例解析

    2023-02-10 07:09:17
  • Android网络数据开关用法简单示例

    2021-07-20 00:06:06
  • JavaEE组件commons-fileupload实现文件上传、下载

    2022-11-13 13:54:20
  • Android实现长截屏功能

    2022-03-02 15:20:27
  • js事件模型与自定义事件实例解析

    2021-05-26 06:15:06
  • Android SearchView搜索控件使用方法详解

    2022-07-09 16:49:21
  • C语言函数封装及变量的作用域

    2022-10-06 10:14:47
  • C#使用Socket实现本地多人聊天室

    2022-01-06 12:47:27
  • Java实战之用springboot+netty实现简单的一对一聊天

    2023-12-03 07:28:19
  • Java+Swing实现医院管理系统的完整代码

    2023-03-17 00:40:21
  • C#分屏控件用法实例

    2022-02-04 20:01:57
  • Spring MVC项目中的异常处理详解

    2021-12-22 09:19:20
  • C# 中使用正则表达式匹配字符的含义

    2023-11-19 02:59:38
  • C#中数组初始化与数组元素复制的方法

    2023-05-14 15:45:06
  • Android开发中Bitmap高效加载使用详解

    2021-06-05 01:32:15
  • C#实现Base64编码与解码及规则

    2023-09-17 13:06:19
  • asp之家 软件编程 m.aspxhome.com