看看我给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遇到问题也能够直接去官方仓库查看。