K8S下應用異常卡頓問題的分析與學習

K8S下應用異常卡頓問題的分析與學習


背景

週二自己在處理申威服務器的問題時, 被同事拉進一個羣聊.
告知客戶現場有一個特殊情況: 
服務晚上重啓,  上午速度還可以, 但是到了下午就開始變的非常卡頓.

因爲當時正在車上也看不到具體信息. 
晚上九點上會進行了一次簡單查看.

發現GC非常平穩, 容器內的CPU和內存都和很正常
部署模式是 華爲鯤鵬服務器上面的 華爲雲 K8S集羣
容器部署.

第一次問題分析

第一天沒有上手操作(這是一個敗筆)
根據現場同事的說明進行了簡單的判斷. 

啓動參數問題不大, 資源沒問題 , GC沒問題
同事一開始懷疑是 虛擬化擠壓導致的性能下降
我通過gclog發現GC時間變化不大, 排除了這一個可能. 

但是懷疑自己分析錯了 top -Hp的文件,導致出現誤判
懷疑的方向到了 東方通中間件. 以爲是中間件的問題. 

第二次問題分析

週三下午問題依舊. 
不過也排除了東方通的問題, 不算是沒收穫.
沒辦法緊急聯繫了華爲雲的運維人員
進行了一些簡單的溝通
發現大家都一樣, 認爲自己沒問題. 
都是別人的問題. 
雲平臺說別人沒問題, 就你們有問題
我們說大項目都沒問題,就這個項目有問題.
沒辦法繼續折騰 

週三其實沒有特別大的發現, 想着繼續看看

第三次問題分析

週四下午問題繼續 !-_-!
正好下午有時間可以遠程, 趁着六點客戶使用低谷期進行了驗證
週三其實還是有一個收穫的, 看到華爲雲有一個jvm的監控
週四自己能操作, 多看了會兒, 發現 codecache 是一個深坑, 只有 48MB
然後繼續上手操作: 
其實方法還是一樣的. 
第一步 docker exec -it $containerid bash 進入容器
第二步 top -Hp 16 然後輸入大寫的 T  查看 現成CPU使用時間
這裏存在一個坑爹的問題, 容器內不顯示具體線程信息, 只顯示java
第三步 jstack -l 16 > 1.txt 然後 cat 1.txt |grep C2 
查看C2 編譯進程的 進程號 發現是 nid=0x32 和 nid=0x33
查看第一步裏面的 50號和51號線程, 發下CPU使用率已經超過了80分鐘. 
注意這裏需要進行 16進制和10進制的轉換. 

基本確認 產品應該是 codecache 太小導致的問題. 

問題解決

增加啓動腳本: 
-XX:InitialCodeCacheSize=1G  -XX:ReservedCodeCacheSize=1G  

第二天進行查看. 
發現 時間基本可控了. 

問題原因確定

拿現場的JDK 到公司內部進行驗證
替換自己的aarch64的 jdk 進行處理
文件名爲:
jdk-8u221-linux-arm64-vfp-hflt.tar.gz
替換之後進行啓動. 發現
 cat jdk1.8.221.txt |grep C2
"C2 CompilerThread1" #6 daemon prio=9 
"C2 CompilerThread0" #5 daemon prio=9 
只有C2沒有C1
[root@NFSV3 ~]# cat jdk1.8.221.txt |grep C1

之前的jdk的情況是: 
[root@NFSV3 ~]# cat jdk18222.txt |grep C1
"C1 CompilerThread20" #25 daemon prio=9 
"C1 CompilerThread19" #24 daemon prio=9 
"C1 CompilerThread18" #23 daemon prio=9 
"C1 CompilerThread17" #22 daemon prio=9 
"C1 CompilerThread16" #21 daemon prio=9 
"C1 CompilerThread15" #20 daemon prio=9 
"C1 CompilerThread14" #19 daemon prio=9 

現場的JDK版本存在問題.  一方面太久, 並且是一個prerelease的.

問題進一步的思考

這個簡單的問題浪費了兩天的時間
(主要是有其他事情在, 自己沒直接上手.)

但是不想浪費時間就這麼白白浪費了
趁着幫人解決問題, 想多進行一下思考和數據獲取

第一個: 爲什麼我這邊正常情況下 服務器返回而也有 300ms.
不應該這麼多的, 公司內x86的機器才  20ms左右
自己想到了網絡延遲, 然後ping了下,發現延遲在 40ms. 
自己與項目所在地的距離應該是
好幾千公里.  所以理論上在局域網應該會少40ms
然後讓交付進行了驗證, 的確現場大概是 250ms 左右

第二個: 想到了是容器化部署的情況
我讓交付同事直接使用node:port的方式進行查看時延的情況
發現延遲也差不多 250ms
所以懷疑 K8S的出口有一個較大行的網絡設備影響了網絡延遲. 
公司內最快15ms.明顯網絡設備產生了 240ms的延遲. 

問題進一步思考之二

爲啥方法區默認是48MB
現場同事很細心, 立馬發現 分層編譯時默認值是 240MB
不啓用分層編譯是  48MB
但是我們沒有明確在指定不使用分層編譯
所以這是一個什麼鬼? 

又花費了了一段時間進行排查, 暫未發現
感覺可以問問呢 華爲雲或者是 jdk的版本? 

問題的進一步思考之三

其實如果有perf 或者是 epbf 
或者是使用arthas 或者是 async profiler
可以通過查看火焰圖裏面大的平臺
如果升級jdk 可以使用jfr 然後同構jmc進行分析

估計也可以看到是 complie 相關
也可以確定這個問題原因
但是現場沒有部署這一些工具, 部署工具有擔心影響性能. 

所以很多問題是需要循序漸進的. 
提高自己的武器庫才重要
不能盲猜不能盲信. 

問題的進一步思考之四

需要統一交付物
這幾天幫助同事進行處理. 
他找了一圈都沒找到openjdk的下載點
自己下載的這個jdk有bug 
也不能怪這位同事.

還是需要有一個統一的知識庫和可以獲取下載的點的. 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章