1. 程式人生 > >從原始碼研究如何不重啟Springboot專案實現redis配置動態切換

從原始碼研究如何不重啟Springboot專案實現redis配置動態切換

上一篇Websocket的續篇暫時還沒有動手寫,這篇算是插播吧。今天講講不重啟專案動態切換redis服務。 **背景** 多個專案或微服務場景下,各個專案都需要配置redis資料來源。但是,每當運維搞事時(修改redis服務地址或埠),各個專案都需要進行重啟才能連線上最新的redis配置。服務一多,修改各個專案配置然後重啟專案就非常蛋疼。所以我們想要找到一個可行的解決方案,能夠不重啟專案的情況下,修改配置,動態切換redis服務。 **如何實現切換redis連線** 剛遇到這個問題的時候,想必如果對spring-boot-starter-data-redis不是很熟悉的人,首先想到的就是去百度一下(安慰下自己:不要重複造輪子嘛)。 可是一陣百度之後,你找到的結果可能都是這樣的: ``` public ValueOperations updateRedisConfig() { JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory) stringRedisTemplate.getConnectionFactory(); jedisConnectionFactory.setDatabase(db); stringRedisTemplate.setConnectionFactory(jedisConnectionFactory); ValueOperations valueOperations = stringRedisTemplate.opsForValue(); return ValueOperations; ``` 沒錯,絕大多數都是切換redis db的程式碼,而沒有切redis服務地址或賬號密碼的。而且天下程式碼一大抄,大多數部落格都是一樣的內容,這就讓人很噁心。 沒辦法,網上沒有,只能自己造輪子了。不過,從強哥這種懶人思維來說,上面的程式碼既然能切庫,那是不是host、username、password也同樣可以,於是我們加入如下程式碼: ``` public ValueOperations updateRedisConfig() { JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory) stringRedisTemplate.getConnectionFactory(); jedisConnectionFactory.setDatabase(db); jedisConnectionFactory.setHostName(host); jedisConnectionFactory.setPort(port); jedisConnectionFactory.setPassword(password); stringRedisTemplate.setConnectionFactory(jedisConnectionFactory); ValueOperations valueOperations = stringRedisTemplate.opsForValue(); return valueOperations; } ``` 話不多說,改完重啟一下。額,執行結果並沒有讓我們見證奇蹟的時刻。在呼叫updateRedisConfig方法的之後,使用redisTemplate還是隻能切換db,不能進行服務地址或賬號密碼的更新。 這就讓人頭疼了,不過想也沒錯,如果可以的話,網上不應該找不到類似的程式碼。那麼,現在該咋辦嘞? 強哥的想法是:redisTemplate每次獲取ValueOperations執行get/set方法的時候,都會去連線redis伺服器,那麼我們就從這兩個方法入手看看能不能找得到解決方案。 接下來就是原始碼研究的過程啦,有耐心的小夥伴就跟著強哥一起找,只想要結果的就跳到文末吧~ 首先來看看入手工具方法set: ``` public boolean set(final String key, Object value) { boolean result = false; try { ValueOperations