一次Docker中Redis連接暴增的問題排查實(shí)戰(zhàn)記錄
周六生產(chǎn)服務(wù)器出現(xiàn)redis服務(wù)器不可用狀態(tài),錯誤信息為:
狀態(tài)不可用,等待后臺檢查程序恢復(fù)方可使用。Unexpected end of stream; expected type 'Status'
如下圖所示,下圖6300就是我們redis服務(wù)器運(yùn)行的端口。
頭一次碰到此類問題,心想難道是redis掛掉了,隨即通過telnet ip+端口。發(fā)現(xiàn)運(yùn)行正常,然后就想著進(jìn)入redis看下目前連接情況。一看發(fā)現(xiàn)竟然高達(dá)1903條這么多。
然后想著應(yīng)該是代碼創(chuàng)建redis連接過多導(dǎo)致的,查看代碼。
發(fā)現(xiàn)redis創(chuàng)建只有這一個地方有,這里也是服務(wù)注冊時才執(zhí)行。也就是應(yīng)用程序啟動時才被執(zhí)行一次。然后整個項(xiàng)目查找,沒有其他地方再有調(diào)用redis初始化。
心有不甘,難道是每次在redis讀寫數(shù)據(jù)時都會創(chuàng)建連接嗎?會和讀寫頻繁有關(guān)系嗎?總感覺不會啊,隨即創(chuàng)建測試代碼進(jìn)行測試一番。
在本地搭建了一個redis環(huán)境,測試之前先看看接數(shù)多少,目前看只有1個,也就是目前的cmd連接客戶端,這個屬于正常的了。
開始測試,運(yùn)行程序。代碼是創(chuàng)建一個連接對象,并一共測試1000次寫,和1000次讀。
不管我怎么測試連接都是6個,那么也就是說我們程序最多創(chuàng)建了5個連接,當(dāng)然主要有線程池在里面。
所以基本的存儲讀取這塊代碼肯定是沒問題。
但代碼這塊也沒算完全放棄排查,因?yàn)樯a(chǎn)服務(wù)器通過docker運(yùn)行著大約6個應(yīng)用程序。都是連接的同一個redis,會不會是其他應(yīng)用程序?qū)е碌模?/p>
然后就想直接通過redis 連接列表里的中隨便一個端口來查詢對應(yīng)的進(jìn)程信息就可以知道是哪些應(yīng)用程序了。
Linux 中通過查詢網(wǎng)絡(luò)端口號顯示進(jìn)程信息。
netstat -atunlp | grep 60852
首先看這端口對應(yīng)的IP,比如這里第一個是172.17.0.1。熟悉docker的同學(xué)應(yīng)該知道這個ip是docker網(wǎng)關(guān)IP。我們?nèi)萜髦械某绦蚨际峭ㄟ^這個網(wǎng)關(guān)IP來和我們宿主主機(jī)來通訊的。我們通過ifconfig就能發(fā)現(xiàn)docker這個網(wǎng)關(guān)IP,第二個172.17.0.3:6379這個一看就是redis的容器IP,
這樣一看確實(shí)無法找到具體對應(yīng)哪個容器中的程序和我們建立連接的。
有一個最笨的辦法就是挨個進(jìn)入容器里面。即docker exec –it test /bin/bash 然后查看當(dāng)前容器的網(wǎng)絡(luò)連接情況。這樣非常麻煩,并且需要安裝很多組件才能執(zhí)行一系列命令。
另外一個辦法lsof命令,如果沒有則需要安裝。我們可以通過進(jìn)程去找所有網(wǎng)絡(luò)連接情況。
比如我們剛發(fā)現(xiàn)我們的進(jìn)程主要是docker,他的pid是582251。
lsof -i |grep 582251
或者 lsof -i -p 582251
結(jié)果如下圖,右邊其實(shí)出現(xiàn)了具體IP,這個IP就是docker容器具體的IP地址。
現(xiàn)在知道所有IP和端口了,我們將命令執(zhí)行結(jié)果下載下來。
首先找到自己每個容器對應(yīng)的IP。
docker inspect name |grep IPAddress //name 容器名稱或者id
找到每個ip后然后根據(jù)剛下載的所有網(wǎng)絡(luò)連接信息進(jìn)行統(tǒng)計(jì),看哪個IP連接最多,最多的一個肯定有問題。
然后我就找到這個IP對應(yīng)的容器部署的程序,然后看redis配置。發(fā)現(xiàn)線程池設(shè)為200。
另外我通過github,發(fā)現(xiàn)CSRedisCore還有個預(yù)熱機(jī)制,也就是preheat,他默認(rèn)值就是5個預(yù)熱連接。
我們線程池設(shè)置的是200加上本身有個預(yù)熱機(jī)制5個連接,我不知道是不是會創(chuàng)建200*5=1000個。這個有時間再好好研究下源代碼,目前只是猜測。
我現(xiàn)在已經(jīng)將redis修改為poolsize=5, preheat=false。線程池5個,并且關(guān)閉預(yù)熱機(jī)制。
修改我們連接配置,并重啟應(yīng)用服務(wù)器和redis服務(wù)器(為了徹底清除已建立的連接)后發(fā)現(xiàn)連接數(shù)有減少,但沒有很多。后來查詢發(fā)現(xiàn),是redis的idle空閑時長太長,導(dǎo)致連接池維持太多連接,沒有被釋放。
我們設(shè)置下超時為30s
執(zhí)行CONFIG SET timeout 30 (單位是秒,此種方式只是臨時修改,針對當(dāng)前運(yùn)行有效。長效記得修改redis配置文件)
然后再看下連接數(shù)多少,這樣一下子就減少了很多。
總結(jié):
1、 redis連接暴增,首先從自身應(yīng)用程序出發(fā)去尋找問題,比如我這邊發(fā)現(xiàn)的連接池設(shè)置過大,加上默認(rèn)的預(yù)熱機(jī)制等。還有盡可能的看代碼層面在創(chuàng)建連接是否會被多次觸發(fā),如果有就必須要改正?,F(xiàn)在都是通過注入的方式創(chuàng)建實(shí)例,要看該地方是存在被多次調(diào)用。
2、修改redis服務(wù)器配置,比如連接空閑超時時間。包括也可也看下最大連接數(shù)多少,默認(rèn)值。
到此這篇關(guān)于Docker中Redis連接暴增的問題排查的文章就介紹到這了,更多相關(guān)Docker中Redis連接暴增問題排查內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Docker學(xué)習(xí)筆記之Docker端口映射
本篇文章主要介紹了Docker學(xué)習(xí)筆記之Docker端口映射,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07一次Docker中Redis連接暴增的問題排查實(shí)戰(zhàn)記錄
這篇文章主要給大家介紹了一次Docker中Redis連接暴增的問題排查的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06使用Docker部署Angular項(xiàng)目的方法步驟
這篇文章主要介紹了使用Docker部署Angular項(xiàng)目的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12docker網(wǎng)卡的IP地址修改方法總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于docker網(wǎng)卡的IP地址修改方法,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用docker具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-06-06Docker本地部署Drupal并實(shí)現(xiàn)公網(wǎng)訪問的詳細(xì)步驟
Drupal是使用PHP語言編寫的開源內(nèi)容管理框架(CMF),它由內(nèi)容管理系統(tǒng)(CMS)和PHP開發(fā)框架(Framework)共同構(gòu)成,這篇文章主要給大家介紹了關(guān)于Docker本地部署Drupal并實(shí)現(xiàn)公網(wǎng)訪問的詳細(xì)步驟,需要的朋友可以參考下2023-12-12Docker容器如何查看ip地址的實(shí)現(xiàn)方法
這篇文章主要介紹了Docker容器如何查看ip地址的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09詳解docker進(jìn)行數(shù)據(jù)掛載的三種模式
Docker?提供了三種方式將數(shù)據(jù)從宿主機(jī)掛載到?Docker容器中:?volumes、bind?mounts、tmpfs?,這篇文章主要介紹了docker進(jìn)行數(shù)據(jù)掛載的三種模式,需要的朋友可以參考下2022-05-05Prometheus 整合 AlertManager的教程詳解
Alertmanager 主要用于接收 Prometheus 發(fā)送的告警信息,它很容易做到告警信息的去重,降噪,分組,策略路由,是一款前衛(wèi)的告警通知系統(tǒng)。這篇文章主要介紹了Prometheus 整合 AlertManager的教程 ,需要的朋友可以參考下2019-07-07