看看我給Arthas官方提供的容器中生成火焰圖問題解決方案

Arthas(阿爾薩斯)是阿里巴巴開源的 Java 診斷工具,深受開發者喜好。java

  • 當你遇到如下相似問題而一籌莫展時,Arthas 能夠幫助你解決:node

  • 這個類從哪一個 jar 包加載的?爲何會報各類類相關的 Exception?linux

  • 我改的代碼爲何沒有執行到?難道是我沒 commit?分支搞錯了?c++

  • 遇到問題沒法在線上 debug,難道只能經過加日誌再從新發布嗎?git

  • 線上遇到某個用戶的數據處理有問題,但線上一樣沒法 debug,線下沒法重現!github

  • 是否有一個全局視角來查看系統的運行情況?spring

  • 有什麼辦法能夠監控到JVM的實時運行狀態?docker

1、背景

arthas的github倉庫中曾經有人提過這樣一個issue。錯誤信息以下:tomcat

Perf events unavailable. See stderr of the target process.

爲何我要寫這篇博客,筆者在arthas官方倉庫中發現官方的回覆裏只是給了一個指向async-profiler官方的地址, 不少人可能順着給出的地址去async-profiler官方文檔看了也是很是的懵。而且async-profiler描述也不必定找到好的解決方案。 所以,寫這邊博客的目的是幫助你們後續在遇到這個問題時可以有一個其它的方案去解決問題。 下面筆者將帶着你們一步一步的解決,arthas在容器中生成火焰圖報錯的問題。安全

2、 alpine容器鏡像中生成火焰圖

如何在本身的鏡像中添加arthas,請直接看官方網站,若是不瞭解的怎麼使用arthas的同窗也請先去官網看資料。

生成火焰圖:

[arthas@1]$ profiler start
AsyncProfiler error: /opt/arthas/async-profiler/libasyncProfiler-linux-x64.so: libstdc++.so.6: cannot open shared object file or directory

執行命令後發現alpine基礎鏡像中缺少libstdc++.so.6庫,遇事不要慌,如今安裝下libstdc++。

[root@node-znjj-131-146 testYaml]# kubectl exec -it springboot-tomcat-deployment-7577ccdd9d-4rpc4 /bin/bash
bash-4.4# apk add libstdc++
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/1) Installing libstdc++ (8.3.0-r0)
Executing glibc-bin-2.29-r0.trigger
OK: 32 MiB in 39 packages

安裝完成後在執行arthas的生成火焰圖命令。

[arthas@1]$ profiler start
Perf events unavailable. See stderr of the target process.

很差了,又出現了新的問題了。這個問題一般是出如今容器環境中。 arthus實際是利用async-profiler去完成的。在async-profiler官方地址的README中有提到改問題。

Perf events unavailble. See stderr of the target process.

perf_event_open() syscall has failed. The error message is printed to the error stream of the target JVM.

Typical reasons include:

  • /proc/sys/kernel/perf_event_paranoid is set to restricted mode (>=2). /proc/sys/kernel/perf_event_paranoid 設置爲受限模式(> = 2)

  • seccomp disables perf_event_open API in a container(seccomp禁用容器中的perf_event_open API。).

  • OS runs under a hypervisor that does not virtualize performance counters.(操做系統在不虛擬化性能計數器的管理程序下運行。)

  • perf_event_open API is not supported on this system, e.g. WSL.(該系統不支持perf_event_open API,例如WSL。)

咱們這裏來好看下系統的/proc/sys/kernel/perf_event_paranoid 這個配置項。

bash-4.4# cat /proc/sys/kernel/perf_event_paranoid
2

發現該系統配置參數的值確實是大於等於2。 根據官方文檔的描述。嘗試將/proc/sys/kernel/perf_event_paranoid的值設置爲1。

bash-4.4# echo 1 > /proc/sys/kernel/perf_event_paranoid
bash-4.4# bash: /proc/sys/kernel/perf_event_paranoid: Read-only file system

說明權限不足。這時問題又來,一般狀況下基礎鏡像的都是使用的非root權限。若是咱們硬要修改這個配置項,第一想到的可能只能從新構建鏡像了。在構建鏡像的時候修改基礎鏡像的用戶,而後設置系統參數。

這帶來了新的問題:

  • 新的基礎鏡像變動後帶來了安全問題。
  • 全部須要的嘗試生成火焰圖的更改基礎鏡像。

這是稍微思考下,咱們發現kubernetes下或者docker中都容許咱們變動容器的權限。

在docker中可使用--cap-add SYS_ADMIN命令選項來指定。

docker run  --cap-add=SYS_ADMIN {container}

在kubernetes中能夠經過securityContext來設置。修改你的deployment部署文件,配置參考以下。

containers:
    - name: springboot-tomcat
      image: registry.cn-shanghai.aliyuncs.com/shalousun/springboot:2.3.4-tomcat
      imagePullPolicy: Always
      securityContext:
        capabilities:
          add: ["SYS_ADMIN"]

配置好後從新在kubernetes中部署就行了。部署好從新進入容器後就能夠正常按照arthas官方的命令執行了。

[arthas@1]$ profiler start
Started [cpu] profiling
[arthas@1]$ profiler getSamples
3
[arthas@1]$ profiler status
[perf] profiling is running for 28 seconds
[arthas@1]$ profiler stop
OK
profiler output file: /arthas-output/20201109-181906.svg

經筆者測試,不管你的基礎鏡像裏面用的是openjdk仍是oracle jdk。缺少libstdc++你均可以使用上述的方式解決。

鳴謝

感謝阿里開源爲java開發者提供一個這個好的性能和問題的排查工具。

總結

筆者已經把問題的解決方案提交給了arthas官方,並被收錄爲了use-case。後續使用arthas遇到問題也能夠直接去官方倉庫查看。

相關文章
相關標籤/搜索