問題出現
同事說訪問nginx服務時常出現502錯誤,但是由於我是第一天入職,對於公司架構不了解,所以根據現象,去查看nginx服務日志
日志內容如下:
2020/09/07 14:04:02 [error] 2334#0: *16623399 connect() failed (111: Connection refused) while connecting to upstream, client: 112.17.165.197, server: testapi.sdhwl.vip, request: "GET /tmsUcenter/members/accountInfo HTTP/1.1", upstream: "http://172.21.0.8:7122//tmsUcenter/members/accountInfo", host: "192.144.168.25:21111"
2020/09/07 14:04:02 [error] 2334#0: *16623399 connect() failed (111: Connection refused) while connecting to upstream, client: 112.17.165.197, server: testapi.sdhwl.vip, request: "GET /tmsUcenter/members/accountInfo HTTP/1.1", upstream: "http://172.21.0.8:7122//tmsUcenter/members/accountInfo", host: "192.144.168.25:21111"
2020/09/07 14:04:02 [error] 2334#0: *16623399 connect() failed (111: Connection refused) while connecting to upstream, client: 112.17.165.197, server: testapi.sdhwl.vip, request: "GET /tmsUcenter/members/accountInfo HTTP/1.1", upstream: "http://172.21.0.8:7122//tmsUcenter/members/accountInfo", host: "192.144.168.25:21111
定位問題
根據日志信息,去查看nginx的配置文件,發現公司的nginx服務中有一個nginx是單獨用於轉發請求給docker容器的,查看服務器中運行的docker容器。
定位到問題出現在某個container掛掉,無法處理nginx轉發過來的請求,導致訪問時出現502現象
問題困擾
既然定位到是container的問題,將container重啟就可以恢復。
重啟container出現了關鍵原因
docker stop 指定的容器 后 docker ps -a 發現仍然up
通過查看linux系統的message日志
日志內容如下:
Sep 7 15:32:13 db-41 dockerd: time="2020-09-07T15:32:13.605724773+08:00" level=info msg="Container 5f3f92db000faa32beef775b6fe4c41d5041a85eb88ece1318c83b5a0b709a61 failed to exit within 10 seconds of signal 15 - using the force"
Sep 7 15:32:13 db-41 dockerd: time="2020-09-07T15:32:13.607162887+08:00" level=warning msg="container kill failed because of 'container not found' or 'no such process': Cannot kill container 5f3f92db000faa32beef775b6fe4c41d5041a85eb88ece1318c83b5a0b709a61: rpc error: code = 2 desc = containerd: container not found"
Sep 7 15:32:23 db-41 dockerd: time="2020-09-07T15:32:23.607430044+08:00" level=info msg="Container 5f3f92db000f failed to exit within 10 seconds of kill - trying direct SIGKILL"
未能在信號15發出后10秒內退出
既然停不掉,索性就up狀態吧
我進入容器確認一下是否因為某個進程的不存在導致了無法處理請求。
docker exec -it 指定容器 /bin/bash
rpc error: code = 2 desc = containerd: container not found
沒有發現這個容器
messages中顯示container沒有執行退出命令
報錯信息顯示 container容器已經不存在了
因為之前遇到過進程僵死的情況
首先懷疑的內存OOM機制的原因,導致了container(本質上也是一個進程)僵死。
free -h
內存確實十分嚴重,32G的內存 15G的swap已經所剩無幾。
更加懷疑是引發了Linux的OOM機制(OMM機制會根據占用內存的大小進行kill,內存占用越大,被kill的幾率越大)
既然正常的方式無法刪除container,則拿出殺手鐧docker rm -f container
在docker rm -f container 之前確保能啟動一個一樣的container
收集信息
1、重新運行container所需要的信息
docker inspect信息
container port 信息
nginx轉發信息
container network信息
container volume信息
看到是null后便認為是container中設定好的目錄信息,沒有涉及到linux系統本地目錄mount(因忽略此目錄映射導致 被困擾了一段時間)
2、同事反饋
過一段時間便會出現此現象,每次都是和上屆運維進行口頭通知,也不知道他是怎么修復的,一會兒就好,但是隔一段時間還是會出現。
問題進展
一、先解決問題
docker commit -a "liushiya" -m "backup" 4746760911cc(ID) 命名
docker run -d -p -it /bin/bash
docker rm -f docker_name
docker run -it -p 7122:7122 --name="sdh-tms-ucenter" sdh-tms-ucenter_backup:latest sh -c 'java -Dspring.config.location=/data/sdh_micro_service/sdh-tms-ucenter/1.0/application.yml -Dloader.path=/data/sdh_micro_service/libs -jar /data/sdh_micro_service/sdh-tms-ucenter/1.0/sdh-tms-ucenter-1.0.jar --server.port=7122 >> /data/sdh_micro_service/log/sdh-tms-ucenter-1.0.jar.log 2>&1'
run -d -it 夯不住
-it 報錯沒有此目錄
通過大佬提醒,第二天回到公司查看確實是映射了本地目錄,正常啟動container,暫時解決502問題,測試同事繼續正常工作。
二、分析出現問題的原因
①進程占用內存的大小信息
cat /proc/進程號/status
VmRSS //進程當前使用的物理內存的大小
VmData //進程占用的數據段大小
VmSize //進程當前使用的虛擬內存的大小
②內核日志信息
dmesg|grep memory
(詳細解釋dmesg命令參照玉樹臨風的博客)
③殺死進程的日志
egrep -i -r 'killed process' /var/log/messages
在周五 container又一次死掉了。查詢日志, 還真在日志中發現了被殺死的container進程號,更加確信是因為引發了OOM機制問題而導致時常擋掉的想法。(有部分博客說是docker的版本bug問題,公司docker版本為舊版本,所以當時這個觀點我也要考慮)
治標不治本
container重新拉起來 可以暫時解決問題,我也寫了定時任務crontab 每隔一小時重啟container(省的老是叫我手動重啟 O(∩_∩)O)
困惑
今天周一查看時 container又死掉了 並且在日志中沒有發現被OOM殺死的container進程
的信息
如果說我之前堅持引發OOM的觀點,則此時的我困惑了 嗚嗚嗚~
柳暗花明
最后經過長時間的關注,此容器代碼有大部分的冗余,導致占用內存極大,並多次發現OOM信息(雖然上面記錄為周一沒發現OOM信息,但是大部分都在對應的時間點找到了OOM日志信息)。
最終定位問題為:服務組件代碼大量冗余,占用內存資源極大,引發OOM導致容器宕掉。
解決方法:反饋給開發同事,在總監的帶領下重構這部分組件的代碼,內存限制放開,機器資源適當增加,沒再出現此類現象。