redis發布訂閱客戶端報錯


  轉自簡書【https://www.jianshu.com/p/a85ec38245da

  最近遇到一個問題,springBoot程序中有一個監聽器,監聽redis中發來的消息(其實是監聽一個key的消失,以此做定時),后台程序監聽不到redis消息。

  剛開始以為是redis鍵值未寫入,或者過期時間不對,經過排查,在定時開始時,key已經寫入,並且過期時間與系統中設置的一致。並且未見明顯報錯,直到在控制台發現:

2019-10-11 09:16:14,574 ERROR [rules-engine-4]  o.s.d.r.l.RedisMessageListenerContainer - Connection failure occurred. Restarting subscription task after 5000 ms
2019-10-11 09:16:14,597 ERROR [agentconnection-pubsub-50]  o.s.d.r.l.RedisMessageListenerContainer - Connection failure occurred. Restarting subscription task after 5000 ms
2019-10-11 09:16:14,599 ERROR [servicesession-expire-84]  o.s.d.r.l.RedisMessageListenerContainer - Connection failure occurred. Restarting subscription task after 5000 ms

  這時候才反應過來后台程序與redis連接出現了問題。

  1)百度查看該報錯,很多是說:Redis訂閱客戶端訂閱buffer超過32M或持續60秒超過8M,訂閱立即被關閉!(意思是說客戶端消費速度比較慢,導致產生的消息大量堆積超過了限制客戶端被關閉)

client-output-buffer-limit pubsub 32mb 8mb 60

  2)可以修改配置為(使其不受限制):

config set client-output-buffer-limit "normal 0 0 0 slave 268435456 67108864 60 pubsub 0 0 0"

  3)這次遇到的問題好像不是這樣的,看到 “client-output-buffer-limit pubsub如果達到限制會關閉客戶端,然后客戶端會報此次這個錯誤,那是不是有可能是其他地方將這個客戶端關閉了造成這個錯誤;”

  4)服務器的redis是部署在阿里雲,並且使用了haproxy(這個東西沒用過,還得學習,貼一張其他博主的圖紀錄一下)

timeout client:客戶端非活動狀態的超時時長  
timeout server:客戶端與服務器端建立連接后,等待服務器端的超時時長
並借用了別人的解決方案
  • 暫時解決方案
    1)haproxy超時時間仍改回3min,因為后端代理了mysql等服務;
    2)暫時繼續沿用目前這種方案,因為程序具備斷開重連機制,雖然redis發布訂閱不能持久化,斷開連接期間發布的消息訂閱端有可能丟失,但是目前業務發布消息很少,幾個月發布一次消息,在發布消息的時候連接斷開的概率還是比較小的,所以暫不處理。
  • 永久解決方案
    1)采用Rabbit Mq取代redis
    2)tomcat直連redis
    3)代碼處增加額外的發布信息,確保連接idle時間不會超過3min
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM