前段時間,由于線上redis服務器的內存使用率達到了機器總內存的50%以上,導致內存數據的dump持久化一直失敗。擴展到多臺redis后,應用系統訪問redis時, 在業務量較少時,時不時會出現以下異常,當業務量較大,redis訪問頻率很高時,卻不會發生這個異常 ,一
前段時間,由于線上redis服務器的內存使用率達到了機器總內存的50%以上,導致內存數據的dump持久化一直失敗。擴展到多臺redis后,應用系統訪問redis時,在業務量較少時,時不時會出現以下異常,當業務量較大,redis訪問頻率很高時,卻不會發生這個異常,一時覺得很詭異。
redis.clients.jedis.exceptions.JedisConnectionException:?It?seems?like?server?has?closed?the?connection.
at?redis.clients.util.RedisInputStream.readLine(RedisInputStream.java:90)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Protocol.processInteger(Protocol.java:110)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Protocol.process(Protocol.java:70)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Protocol.read(Protocol.java:131)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Connection.getIntegerReply(Connection.java:188)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Jedis.sismember(Jedis.java:1266)?~[jedis-2.1.0.jar:na]
看提示,應該是服務端主動關閉了連接。查看了新上線的redis服務器的配置,有這么一項:
# Close the connection after a client is idle for N seconds (0 to disable) timeout 120
這項配置指的是客戶端連接空閑超過多少秒后,服務端主動關閉連接,默認值0表示服務端永遠不主動關閉。而op人員把服務器端的超時時間設置為了120秒。這就解釋了發生這個異常的原因。客戶端使用了一個連接池管理訪問redis的所有連接,這些連接是長連接,當業務量較小時,客戶端部分連接使用率較低,當兩次使用之間的間隔超過120秒時,redis服務端就主動關閉了這個連接,而等客戶端下次再使用這個連接對象時,發現服務端已經關閉了連接,進而報錯。
解決方案有兩種:
1. 在redis-cli下直接修改redis 的配置,把timeout改回為0,無需重啟redis即可直接生效。
2. 修改應用系統代碼,設置連接的最大空閑時長(超出此時長將斷開空閑連接)小于120秒。
出于改動成本考慮,采用了第一種方案,修改后,報錯不再出現。
這里有一個問題,為何服務器端主動關閉空閑連接后,客戶端沒有報錯呢,系統依賴的是jedis-2.1.0,這塊需要細看下jedis連接池那塊的實現,jedis連接池主要是基于commons-pool寫的,下來再研究研究,寫一篇文章總結一下。
(本文已被閱讀18次)
前段時間,由于線上redis服務器的內存使用率達到了機器總內存的50%以上,導致內存數據的dump持久化一直失敗。擴展到多臺redis后,應用系統訪問redis時,在業務量較少時,時不時會出現以下異常,當業務量較大,redis訪問頻率很高時,卻不會發生這個異常,一時覺得很詭異。 redis.clients.jedis.exceptions.JedisConnectionException:?It?seems?like?server?has?closed?the?connection. at?redis.clients.util.RedisInputStream.readLine(RedisInputStream.java:90)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Protocol.processInteger(Protocol.java:110)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Protocol.process(Protocol.java:70)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Protocol.read(Protocol.java:131)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Connection.getIntegerReply(Connection.java:188)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Jedis.sismember(Jedis.java:1266)?~[jedis-2.1.0.jar:na] 看提示,應該是服務端主動關閉了連接。查看了新上線的redis服務器的配置,有這么一項: # Close the connection after a client is idle for N seconds (0 to disable) timeout 120 這項配置指的是客戶端連接空閑超過多少秒后,服務端主動關閉連接,默認值0表示服務端永遠不主動關閉。而op人員把服務器端的超時時間設置為了120秒。這就解釋了發生這個異常的原因。客戶端使用了一個連接池管理訪問redis的所有連接,這些連接是長連接,當業務量較小時,客戶端部分連接使用率較低,當兩次使用之間的間隔超過120秒時,redis服務端就主動關閉了這個連接,而等客戶端下次再使用這個連接對象時,發現服務端已經關閉了連接,進而報錯。 解決方案有兩種: 1. 在redis-cli下直接修改redis 的配置,把timeout改回為0,無需重啟redis即可直接生效。 2. 修改應用系統代碼,設置連接的最大空閑時長(超出此時長將斷開空閑連接)小于120秒。 出于改動成本考慮,采用了第一種方案,修改后,報錯不再出現。 這里有一個問題,為何服務器端主動關閉空閑連接后,客戶端沒有報錯呢,系統依賴的是jedis-2.1.0,這塊需要細看下jedis連接池那塊的實現,jedis連接池主要是基于commons-pool寫的,下來再研究研究,寫一篇文章總結一下。 (本文已被閱讀18次)
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com