在使用Jedis連接池模式下,比較常見的報錯如下:
redis.clients.jedis.exceptions.JedisConnectionException:Could not get a resource from the pool
以華爲雲的分佈式緩存服務(Redis)爲例,首先確認實例是正常運行中狀態,然後按以下步驟進行排查。
網絡
- 覈對IP地址配置
檢查jedis客戶端配置的ip地址是否與緩存實例配置的子網地址一致,如果從公網訪問,則檢查是否與緩存實例綁定的彈性ip地址一致,不一致則修改一致後重試。
- 測試網絡
在客戶端使用ping和Telnet小工具測試網絡。
如果ping不通:
− VPC內訪問時,要求客戶端與緩存實例的VPC相同,安全組相同或者緩存實例的安全組放開了6379端口訪問。
− 公網訪問時,要求緩存實例安全組放開36379端口訪問。
− 如果IP地址可以ping通,telnet對應的端口不通,則嘗試重啓實例,如重啓後仍未恢復,請聯繫華爲雲技術支持。
檢查連接數是否超限
查看已建立的網絡連接數是否超過JedisPool 配置的上限。如果連接數接近配置的上限值,則建議重啓服務觀察。如果明顯沒有接近,排除連接數超限可能。
Unix/Linux系統使用:
netstat-an | grep 6379 | grep ESTABLISHED | wc -l
Windows系統使用:
netstat-an | find "6379" | find "ESTABLISHED" /C
檢查JedisPool連接池代碼
如果連接數接近配置的上限,請分析是業務併發原因,或是沒有正確使用JedisPool所致。
對於JedisPool連接池的操作,每次調用jedisPool.getResource()方法之後,需要調用jedisPool.returnResource()或者jedis.close()進行釋放,優先使用close()方法。
客戶端TIME_WAIT是否過多
通過ss -s查看time wait鏈接是否過多。
如果TIME_WAIT過多,可以調整內核參數(/etc/sysctl.conf):
##當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少量SYN×××
net.ipv4.tcp_syncookies = 1
##允許將TIME-WAITsockets重新用於新的TCP連接
net.ipv4.tcp_tw_reuse = 1
##開啓TCP連接中TIME-WAIT sockets的快速回收
net.ipv4.tcp_tw_recycle = 1
##修改系統默認的TIMEOUT時間
net.ipv4.tcp_fin_timeout = 30
調整後重啓生效:/sbin/sysctl -p
無法解決問題
如果按照以上原因排查之後還有問題,可以通過抓包並將異常時間點、異常信息以及抓包文件發送給華爲雲技術支持協助分析。
抓包可使用tcpdump工具,命令如下:
tcpdump-i eth0 tcp and port 6379 -n -nn -s 74 -w dump.pcap
公網訪問時請將端口改成36379。
網卡名請改成實際的網卡名稱。