溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

一次Docker中Redis連接暴增的問題解決方案

發(fā)布時間:2020-07-22 09:12:22 來源:億速云 閱讀:658 作者:小豬 欄目:服務器

這篇文章主要講解了一次Docker中Redis連接暴增的問題解決方案,內(nèi)容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。

周六生產(chǎn)服務器出現(xiàn)redis服務器不可用狀態(tài),錯誤信息為:

狀態(tài)不可用,等待后臺檢查程序恢復方可使用。Unexpected end of stream; expected type 'Status'

如下圖所示,下圖6300就是我們redis服務器運行的端口。

一次Docker中Redis連接暴增的問題解決方案

頭一次碰到此類問題,心想難道是redis掛掉了,隨即通過telnet ip+端口。發(fā)現(xiàn)運行正常,然后就想著進入redis看下目前連接情況。一看發(fā)現(xiàn)竟然高達1903條這么多。

一次Docker中Redis連接暴增的問題解決方案

然后想著應該是代碼創(chuàng)建redis連接過多導致的,查看代碼。

一次Docker中Redis連接暴增的問題解決方案

發(fā)現(xiàn)redis創(chuàng)建只有這一個地方有,這里也是服務注冊時才執(zhí)行。也就是應用程序啟動時才被執(zhí)行一次。然后整個項目查找,沒有其他地方再有調(diào)用redis初始化。

心有不甘,難道是每次在redis讀寫數(shù)據(jù)時都會創(chuàng)建連接嗎?會和讀寫頻繁有關系嗎?總感覺不會啊,隨即創(chuàng)建測試代碼進行測試一番。

在本地搭建了一個redis環(huán)境,測試之前先看看接數(shù)多少,目前看只有1個,也就是目前的cmd連接客戶端,這個屬于正常的了。

一次Docker中Redis連接暴增的問題解決方案

開始測試,運行程序。代碼是創(chuàng)建一個連接對象,并一共測試1000次寫,和1000次讀。

一次Docker中Redis連接暴增的問題解決方案

不管我怎么測試連接都是6個,那么也就是說我們程序最多創(chuàng)建了5個連接,當然主要有線程池在里面。

一次Docker中Redis連接暴增的問題解決方案

所以基本的存儲讀取這塊代碼肯定是沒問題。

但代碼這塊也沒算完全放棄排查,因為生產(chǎn)服務器通過docker運行著大約6個應用程序。都是連接的同一個redis,會不會是其他應用程序導致的?

然后就想直接通過redis 連接列表里的中隨便一個端口來查詢對應的進程信息就可以知道是哪些應用程序了。

Linux 中通過查詢網(wǎng)絡端口號顯示進程信息。

netstat -atunlp | grep 60852

一次Docker中Redis連接暴增的問題解決方案

首先看這端口對應的IP,比如這里第一個是172.17.0.1。熟悉docker的同學應該知道這個ip是docker網(wǎng)關IP。我們?nèi)萜髦械某绦蚨际峭ㄟ^這個網(wǎng)關IP來和我們宿主主機來通訊的。我們通過ifconfig就能發(fā)現(xiàn)docker這個網(wǎng)關IP,第二個172.17.0.3:6379這個一看就是redis的容器IP,

這樣一看確實無法找到具體對應哪個容器中的程序和我們建立連接的。

有一個最笨的辦法就是挨個進入容器里面。即docker exec –it test /bin/bash 然后查看當前容器的網(wǎng)絡連接情況。這樣非常麻煩,并且需要安裝很多組件才能執(zhí)行一系列命令。

另外一個辦法lsof命令,如果沒有則需要安裝。我們可以通過進程去找所有網(wǎng)絡連接情況。

比如我們剛發(fā)現(xiàn)我們的進程主要是docker,他的pid是582251。

lsof -i |grep 582251或者 lsof -i -p 582251

結果如下圖,右邊其實出現(xiàn)了具體IP,這個IP就是docker容器具體的IP地址。

一次Docker中Redis連接暴增的問題解決方案

現(xiàn)在知道所有IP和端口了,我們將命令執(zhí)行結果下載下來。

首先找到自己每個容器對應的IP。

docker inspect name |grep IPAddress //name 容器名稱或者id

一次Docker中Redis連接暴增的問題解決方案

找到每個ip后然后根據(jù)剛下載的所有網(wǎng)絡連接信息進行統(tǒng)計,看哪個IP連接最多,最多的一個肯定有問題。

一次Docker中Redis連接暴增的問題解決方案

然后我就找到這個IP對應的容器部署的程序,然后看redis配置。發(fā)現(xiàn)線程池設為200。

一次Docker中Redis連接暴增的問題解決方案

另外我通過github,發(fā)現(xiàn)CSRedisCore還有個預熱機制,也就是preheat,他默認值就是5個預熱連接。

一次Docker中Redis連接暴增的問題解決方案

我們線程池設置的是200加上本身有個預熱機制5個連接,我不知道是不是會創(chuàng)建200*5=1000個。這個有時間再好好研究下源代碼,目前只是猜測。

我現(xiàn)在已經(jīng)將redis修改為poolsize=5, preheat=false。線程池5個,并且關閉預熱機制。

修改我們連接配置,并重啟應用服務器和redis服務器(為了徹底清除已建立的連接)后發(fā)現(xiàn)連接數(shù)有減少,但沒有很多。后來查詢發(fā)現(xiàn),是redis的idle空閑時長太長,導致連接池維持太多連接,沒有被釋放。

一次Docker中Redis連接暴增的問題解決方案

我們設置下超時為30s

執(zhí)行CONFIG SET timeout 30 (單位是秒,此種方式只是臨時修改,針對當前運行有效。長效記得修改redis配置文件)

一次Docker中Redis連接暴增的問題解決方案

然后再看下連接數(shù)多少,這樣一下子就減少了很多。

一次Docker中Redis連接暴增的問題解決方案

總結:

1、 redis連接暴增,首先從自身應用程序出發(fā)去尋找問題,比如我這邊發(fā)現(xiàn)的連接池設置過大,加上默認的預熱機制等。還有盡可能的看代碼層面在創(chuàng)建連接是否會被多次觸發(fā),如果有就必須要改正?,F(xiàn)在都是通過注入的方式創(chuàng)建實例,要看該地方是存在被多次調(diào)用。

2、修改redis服務器配置,比如連接空閑超時時間。包括也可也看下最大連接數(shù)多少,默認值。

看完上述內(nèi)容,是不是對一次Docker中Redis連接暴增的問題解決方案有進一步的了解,如果還想學習更多內(nèi)容,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI