<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
其實最終定位到的問題還是蠻好解決的,但是因為應用在Kubernetes容器中的特殊性,導致在使用Arthas過程中出現了各種問題,所以單獨成文和大家分享下。照例先講下問題發生的背景,一個很老的web系統部署在tomcat容器裡。近期打成了映象丟到了Kubernetes環境中執行,總是各種掛,在Kubernetes層面定位了很久沒找到具體問題,但是初步定位到是因為系統中的報表匯出介面導致的問題,最後使用Arthas找到問題並解決。
首先說下,我們的Kubernetes容器中執行的應用都是基於自己構建的基礎映象打包的,如JDK,和tomcat基礎映象,為了減小打包後應用的體積,我們對JDK進行了大量的刪減,只保留了最小的jre執行時環境。這樣導致的後果是在應用出現問題需要使用jdk工具時,如jinfo、jmap、jstack等都沒了,沒了這些工具就相當於一個戰士沒了武器,束手無策了,但是最後忽然想到了Arthas,java線上排錯利器。
Arthas是阿里巴巴開源的一款線上診斷java應用程式的工具,是greys工具的升級版本,深受開發者喜愛。當你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:
專案地址:https://github.com/alibaba/arthas
第一步:下載arthas-boot.jar
wget https://alibaba.github.io/arthas/arthas-boot.jar
第二步:執行
java -jar arthas-boot.jar
執行後,並沒有出現熟悉的java程序選擇介面,而是一閃而過,如下:
/opt/kl # java -jar arthas-boot.jar [INFO] arthas-boot version: 3.1.0 [INFO] Can not find java process. Try to pass <pid> in command line. Please select an available pid.
按官方的說明檔案描述,假如出現了找不到pid的情況,在當前目錄下應該會輸出相關的log,但是我看了並沒有紀錄檔,那隻能嘗試是否可以手動指定pid來使用Arthas了。在官網沒找到類似說明,只能試試java -jar arthas-boot.jar -help看下,輸出如下
/opt/kl # java -jar arthas-boot.jar -help [INFO] arthas-boot version: 3.1.0 Usage: arthas-boot [-h] [--target-ip <value>] [--telnet-port <value>] [--http-port <value>] [--session-timeout <value>] [--arthas-home <value>] [--use-version <value>] [--repo-mirror <value>] [--versions] [--use-http] [--attach-only] [-c <value>] [-f <value>] [--height <value>] [--width <value>] [-v] [pid] Bootstrap Arthas EXAMPLES: java -jar arthas-boot.jar <pid> java -jar arthas-boot.jar --target-ip 0.0.0.0 java -jar arthas-boot.jar --telnet-port 9999 --http-port -1 java -jar arthas-boot.jar -c 'sysprop; thread' <pid> java -jar arthas-boot.jar -f batch.as <pid> java -jar arthas-boot.jar --use-version 3.0.5 java -jar arthas-boot.jar --versions java -jar arthas-boot.jar --session-timeout 3600 java -jar arthas-boot.jar --attach-only java -jar arthas-boot.jar --repo-mirror aliyun --use-http
EXAMPLES的第一條顯示出來了,直接在jar後面加上pid即可,執行後,還是不行,輸出如下:
/opt/kl # java -jar arthas-boot.jar 1 [INFO] arthas-boot version: 3.1.0 [INFO] Start download arthas from remote server: https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.1.0/arthas-packaging-3.1.0-bin.zip [INFO] Download arthas success. [INFO] arthas home: /root/.arthas/lib/3.1.0/arthas [INFO] Try to attach process 1 Exception in thread "main" java.lang.IllegalArgumentException: Can not find tools.jar under java home: /usr/java/jdk/jre1.8.0_191, please try to start arthas-boot with full path java. Such as /opt/jdk/bin/java -jar arthas-boot.jar at com.taobao.arthas.boot.ProcessUtils.findJavaHome(ProcessUtils.java:195) at com.taobao.arthas.boot.ProcessUtils.startArthasCore(ProcessUtils.java:206) at com.taobao.arthas.boot.Bootstrap.main(Bootstrap.java:441)
根據異常可以明顯看到說找不到tools.jar這個工具包了,還是迴歸到Kubernetes容器環境中因為精簡了jre執行時環境導致jdk很多功能受限了。後面我做了一個非常規的事情,就是在完整的jdk中找到了這個tools.jar,丟到了jre裡的lib目錄中,繼續嘗試,但是還有問題,如下:
/opt/kl # java -jar arthas-boot.jar 1 [INFO] arthas-boot version: 3.1.0 [INFO] arthas home: /root/.arthas/lib/3.1.0/arthas [INFO] Try to attach process 1 [ERROR] Start arthas failed, exception stack trace: java.lang.UnsatisfiedLinkError: no attach in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at sun.tools.attach.LinuxVirtualMachine.<clinit>(LinuxVirtualMachine.java:342) at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:78) at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:250) at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:73) at com.taobao.arthas.core.Arthas.<init>(Arthas.java:26) at com.taobao.arthas.core.Arthas.main(Arthas.java:100) [ERROR] attach fail, targetPid: 1
可以看到在補全了tools.jar之後,出現了新的異常資訊java.lang.UnsatisfiedLinkError: no attach in java.library.path,表明可能我們缺的東西不是一點半點,我們知道attach功能是Arthas實現原理的兩大原理之一。
attach
:jdk1.6新增功能,通過attach機制,可以在jvm執行中,通過pid關聯應用
instrument
:jdk1.5新增功能,通過instrument俗稱javaagent技術,可以修改jvm載入的位元組碼
然後Arthas和其他診斷工具一樣,都是先通過attach連結上目標應用,通過instrument動態修改應用程式的位元組碼達到不重啟應用而監控應用的目的
使用完整的JDK中的java命令。
以上方式都試過不行之後,最後我把完整的JDK給下載到本地了,然後通過jdk的bin目錄下的java命令啟動arthas-boot.jar終於ok了,出現了熟悉的java程序選擇介面:
/opt/kl/jdk1.8.0_191/bin # ./java -jar arthas-boot.jar [INFO] arthas-boot version: 3.1.0 [INFO] Found existing java process, please choose one and hit RETURN. * [1]: 1 org.apache.catalina.startup.Bootstrap
最後定位到的問題其實很簡單,我記錄了Arthas大盤中關於記憶體部分的圖,如下:
上圖從標題列開始往下,分別是heap(堆記憶體)、eden_space(伊甸園區記憶體),survivor_space(倖存者區記憶體)、tenured_gen(老年代記憶體)。這張圖是觸發匯出操作後的記憶體分佈,堆記憶體從一開始的200M左右佔用、到400M、到600M、一瞬間就飈升到900多兆了。最後從堆記憶體指標我們看到,總共989M,使用的記憶體已經飈升到988M了,這個時候其實應用已經掛了,Kubernetes容器已經在重啟這個範例了。到這裡基本已經到位到應用在容器中頻繁掛掉重啟問題的本質了。
最終查明,有方面的原因:
1、因為我們這邊都是spring boot應用,只有一個遺留的tomcat部署的應用,所以在映象優化方面更偏向jdk基礎基礎映象,而tomcat映象沒怎麼關注,一開始對堆記憶體這塊並沒調優設定。
2、後面出現問題後,也確實想到過因為是匯出報表導致應用掛掉,很可能是記憶體問題,設定過tomcat映象內的堆記憶體大小,但是因為我們重新打包的映象沒有使用新的版本號,而是直接覆蓋之前的版本,又使用Jenkins構建的,Jenkins所在主機拉過之前的映象,導致映象更新後,Jenkins打包時並沒有去拉最新的調優過基礎映象。
1、調優過的映象加上新的版本號,讓應用基於新的版本號構建映象。或者清理下Jenkins所在主機的映象,這個會導致第一次構建時速度變慢
2、優化匯出報表的實現,我給的方案是,在匯出巨量資料報表時,可以通過id分割區,分別作業寫入同一個伺服器原生的檔案中,然後讓web容器對映下這個檔案所在的目錄,等所有分割區的任務都結束後,直接組裝一個檔案下載連結返回給前端,讓前端觸發一次讀檔案操作即可。
除了使用Arthas外,最後還嘗試了使用jmap工具,但是因為重新下載的JDK版本和主機jre版本不相容,所有沒用上。最後通過JDK發行的歸檔頁面找到了對應的版本,還是成功的使用jmap -heap pid看到了記憶體情況,。記憶體分佈也蠻清晰的,如:
/opt/kl/jdk1.8.0_191/bin # ./jmap -heap 1 Attaching to process ID 1, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.191-b12 using thread-local object allocation. Mark Sweep Compact GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 3221225472 (3072.0MB) NewSize = 1073741824 (1024.0MB) MaxNewSize = 1073741824 (1024.0MB) OldSize = 2147483648 (2048.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 966393856 (921.625MB) used = 856023096 (816.3672409057617MB) free = 110370760 (105.25775909423828MB) 88.57911199302988% used Eden Space: capacity = 859045888 (819.25MB) used = 787314712 (750.8418197631836MB) free = 71731176 (68.4081802368164MB) 91.6499017104893% used From Space: capacity = 107347968 (102.375MB) used = 68708384 (65.52542114257812MB) free = 38639584 (36.849578857421875MB) 64.00529537736568% used To Space: capacity = 107347968 (102.375MB) used = 0 (0.0MB) free = 107347968 (102.375MB) 0.0% used tenured generation: capacity = 2147483648 (2048.0MB) used = 1521987528 (1451.4804153442383MB) free = 625496120 (596.5195846557617MB) 70.87306715548038% used
jdk歸檔下載頁:https://www.oracle.com/technetwork/java/javase/downloads
Arthas是一個非常不錯的工具,我們線上多次使用Arthas定位過問題。不過像今天的這種Kubernetes容器環境的話,因為本身執行時環境的缺失,可能使用的時候會存在各種問題,這裡主要還是分享個思路。希望能給類似場景的同學提供一個有用的參考。
以上就是Arthas排查Kubernetes中應用頻繁掛掉重啟異常的詳細內容,更多關於Arthas異常排查Kubernetes頻繁重啟的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45