連接池無法獲取到連接或獲取連接超時
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
對於這類問題的原因有幾類,可以根據以下一一進行排查
連接配置錯誤
Jedis連接池配置不可用,redis.host或redis.ip或redis.password 配置有誤,手動檢查配置是否都配置正確。
本地連接池連接數達到最大
連接池中有配置最大連接數maxTotal,本地連接使用達到最大連接數maxTotal。在訪問客戶端上通過netstat -an | grep 6379 | grep EST | wc -l 查看客戶端鏈接數目,如果接近maxTotal, 說明本地連接池資源已經有過耗盡或者正在耗盡。
服務端連接數達到最大
服務端連接數已經超過最大值maxclients,單機的maxclients默認是10000,可以通過redis-cli登錄服務端,使用info 命令查看當前連接數。
$redis-cli -h 10.1**.2.*0 -p 6379
10.1**.2.*0:6379> info clients
# Clients
connected_clients:1004
client_longest_output_list:0
client_biggest_input_buf:1
blocked_clients:0
10.1**.2.*0:6379>
當服務端連接數達到最大,可以通過命令client list,列出連接數,查看age=130222 idle=130222,這兩值表示連接存活的時間和已經空閑的時間。
假如有IP的連接數過大,有可能是客戶端連接使用不規范導致連接泄露。
網絡問題
可以通過客戶端工具redis-cli -h ${IP} -p ${port} -a ${pwd},連接成功后,簡單執行set mykey-i i, del mykey-i 命令,測試redis是否可用。
或者telnet host 6379進行連接,執行多次簡單set del命令測試。
redis連接代碼檢查
獲取JedisPool連接池中的jedis,使用jedis操作redis,每次getResource之后需要調用returnResource或者close進行歸還,可以查看代碼在使用完jedis之后是否returnResource,如果沒有歸還,則非常有可能產生連接泄露。
檢查是否發生nf_conntrack丟包
通過dmesg檢查客戶端是否有異常
nf_conntrack: table full, dropping packet
如果發生nf_conntract丟包可以通過修改設置sysctl -w net.netfilter.nf_conntrack_max=120000
檢查是否TIME_WAIT問題
通過ss -s 查看time wait鏈接是否過多
[root@localhost ~]# ss -s
Total: 314 (kernel 4877)
TCP: 32 (estab 3, closed 1, orphaned 0, synrecv 0, timewait 0/0), ports 0
Transport Total IP IPv6
* 4877 - -
RAW 1 0 1
UDP 2 1 1
TCP 31 13 18
INET 34 14 20
FRAG 0 0 0
如果TIME_WAIT過多可以修改以下參數
sysctl -w net.ipv4.tcp_max_tw_buckets=180000
sysctl -w net.ipv4.tcp_tw_recycle=1
linux文件系統句柄數過小
設置redis同時可以與多少個客戶端進行連接。默認情況下為10000個客戶端。當你
無法設置進程文件句柄限制時,redis會設置為當前的文件句柄限制值減去32,因為redis會為自身內部處理邏輯留一些句柄出來。如果達到了此限制,redis則會拒絕新的連接請求,並且向這些連接請求方發出“max number of clients reached”以作回應。
抓包分析
如果按照上面排查之后還有問題可以通過抓包進行分析。
抓包命令為sudo tcpdump -i eth0 tcp and port 6379 -n -nn -s 74 -w redis.cap。
---------------------
作者:常樂_smile
來源:CSDN
原文:https://blog.csdn.net/li396864285/article/details/78623950
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
