首頁>技術>

週六生產伺服器出現redis伺服器不可用狀態,錯誤資訊為:

狀態不可用,等待後臺檢查程式恢復方可使用。Unexpected end of stream; expected type 'Status'

如下圖所示,下圖6300就是我們redis伺服器執行的埠。

頭一次碰到此類問題,心想難道是redis掛掉了,隨即通過telnet ip+埠。發現執行正常,然後就想著進入redis看下目前連線情況。一看發現竟然高達1903條這麼多。

然後想著應該是程式碼建立redis連線過多導致的,檢視程式碼。

發現redis建立只有這一個地方有,這裡也是服務註冊時才執行。也就是應用程式啟動時才被執行一次。然後整個專案查詢,沒有其他地方再有呼叫redis初始化。

心有不甘,難道是每次在redis讀寫資料時都會建立連線嗎?會和讀寫頻繁有關係嗎?總感覺不會啊,隨即建立測試程式碼進行測試一番。

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

開始測試,執行程式。程式碼是建立一個連線物件,並一共測試1000次寫,和1000次讀。

不管我怎麼測試連線都是6個,那麼也就是說我們程式最多建立了5個連線,當然主要有執行緒池在裡面。

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

但程式碼這塊也沒算完全放棄排查,因為生產伺服器通過docker執行著大約6個應用程式。都是連線的同一個redis,會不會是其他應用程式導致的?

然後就想直接通過redis 連線列表裡的中隨便一個埠來查詢對應的程序資訊就可以知道是哪些應用程式了。

Linux 中通過查詢網路埠號顯示程序資訊。

netstat -atunlp | grep 60852

首先看這埠對應的IP,比如這裡第一個是172.17.0.1。熟悉docker的同學應該知道這個ip是docker閘道器IP。我們容器中的程式都是通過這個閘道器IP來和我們宿主主機來通訊的。我們通過ifconfig就能發現docker這個閘道器IP,第二個172.17.0.3:6379這個一看就是redis的容器IP,

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

有一個最笨的辦法就是挨個進入容器裡面。即docker exec –it test /bin/bash 然後檢視當前容器的網路連線情況。這樣非常麻煩,並且需要安裝很多元件才能執行一系列命令。

另外一個辦法lsof命令,如果沒有則需要安裝。我們可以通過程序去找所有網路連線情況。

比如我們剛發現我們的程序主要是docker,他的pid是582251。

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

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

現在知道所有IP和埠了,我們將命令執行結果下載下來。

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

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

找到每個ip後然後根據剛下載的所有網路連線資訊進行統計,看哪個IP連線最多,最多的一個肯定有問題。

然後我就找到這個IP對應的容器部署的程式,然後看redis配置。發現執行緒池設為200。

另外我通過github,發現CSRedisCore還有個預熱機制,也就是preheat,他預設值就是5個預熱連線。

我們執行緒池設定的是200加上本身有個預熱機制5個連線,我不知道是不是會建立200*5=1000個。這個有時間再好好研究下原始碼,目前只是猜測。

我現在已經將redis修改為poolsize=5, preheat=false。執行緒池5個,並且關閉預熱機制。

修改我們連線配置,並重啟應用伺服器和redis伺服器(為了徹底清除已建立的連線)後發現連線數有減少,但沒有很多。後來查詢發現,是redis的idle空閒時長太長,導致連線池維持太多連線,沒有被釋放。

我們設定下超時為30s

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

然後再看下連線數多少,這樣一下子就減少了很多。

總結:

1、 redis連線暴增,首先從自身應用程式出發去尋找問題,比如我這邊發現的連線池設定過大,加上預設的預熱機制等。還有儘可能的看程式碼層面在建立連線是否會被多次觸發,如果有就必須要改正。現在都是通過注入的方式建立例項,要看該地方是存在被多次呼叫。

2、修改redis伺服器配置,比如連線空閒超時時間。包括也可也看下最大連線數多少,預設值。

連結:https://www.cnblogs.com/rui1236/p/13061696.html

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • un-iapp路由學習,跨平臺執行,支援Android和IOS系統