關於springboot2整合lettuce啟動卡住問題的解決方法
前言
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); } }
總結
到此這篇關於springboot2整合lettuce啟動卡住問題解決的文章就介紹到這瞭,更多相關springboot2整合lettuce啟動卡住內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- SpringBoot實現監控Actuator,關閉redis監測
- SpringBoot整合Redisson的步驟(單機版)
- 解決java連接zookeeper很慢的問題
- Spring整合Mybatis 掃描註解創建Bean報錯的解決方案
- spring如何解決循環依賴問題詳解