[總結]redis連線超時問題排查
阿新 • • 發佈:2018-12-25
連線池無法獲取到連線或獲取連線超時
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 命令檢視當前連線數。當服務端連線數達到最大,可以通過命令client list,列出連線數,檢視age=130222 idle=130222,這兩值表示連線存活的時間和已經空閒的時間。$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>
網路問題
可以通過客戶端工具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連結是否過多
[[email protected] ~]# 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。