Arthas(阿尔萨斯)是阿里巴巴开源的 Java 诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决:
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到JVM的实时运行状态?
alpine容器镜像中生成火焰图
[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中可以使用--c++ap-add SYS_ADMIN命令选项来指定。
docker run --c++ap-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:
c++apabilities:
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
鸣谢
感谢阿里开源为java开发者提供一个这个好的性能和问题的排查工具。
其它开源推荐
关于arthas在容器中生成火焰图遇到的问题,大家可以参考笔者给出的方案。
当然对于java开发者,你如果不喜欢swagger生成api文档的注解侵入,可以了解下笔者开源基于注释生成文档的smart-doc哦。