看看我给Arthas官方提供的容器中生成火焰图问题解决方案

原创
2020/12/03 23:40
阅读数 8.5K

Arthas(阿尔萨斯)是阿里巴巴开源的 Java 诊断工具,深受开发者喜爱。

  • 当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决:

  • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?

  • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?

  • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?

  • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!

  • 是否有一个全局视角来查看系统的运行状况?

  • 有什么办法可以监控到JVM的实时运行状态?

一、背景

arthas的github仓库中曾经有人提过这样一个issue。错误信息如下:

Perf events unavailable. See stderr of the target process.

为什么我要写这篇博客,笔者在arthas官方仓库中发现官方的回复里只是给了一个指向async-profiler官方的地址, 很多人可能顺着给出的地址去async-profiler官方文档看了也是非常的懵。并且async-profiler描述也不一定找到好的解决方案。 因此,写这边博客的目的是帮助大家后续在遇到这个问题时能够有一个其它的方案去解决问题。 下面笔者将带着大家一步一步的解决,arthas在容器中生成火焰图报错的问题。

二、 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遇到问题也可以直接去官方仓库查看。

展开阅读全文
打赏
0
0 收藏
分享
加载中
上官胡闹博主
该评论暂时无法显示,详情咨询 QQ 群:912889742
更多评论
打赏
1 评论
0 收藏
0
分享
返回顶部
顶部