关键字 arthas 生产环境使用arthas调试java应用

官网:arthas

java8可以使用4.0.5

basic

在一个terminal中输入

wget https://arthas.aliyun.com/arthas-demo.jar
java -jar arthas-demo.jar

在另一个terminal中输入

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar --repo-mirror aliyun --use-http

arthas命令

help
bashboard
Q/Ctrl+C # exit
thread tid # show thread statck
thread tid | grep 'main(' # show thread statck contains mainClass
sc -d *MathGame
jad demo.MathGame
watch demo.MathGame primeFactors returnObj  #
exit/quit # exit session
stop # stop arthas

advanced

在一个terminal中输入

wget https://github.com/hengyunabc/spring-boot-inside/raw/master/demo-arthas-spring-boot/demo-arthas-spring-boot.jar
java -jar demo-arthas-spring-boot.jar

在另一个terminal中输入

java -jar arthas-boot.jar --target-ip 0.0.0.0

arthas命令

sysprop # show all system properties
sysprop java.version # show by key name
sysprop | grep user # filter key
sysprop | wc -l # count key
sysprop testKey testValue  # set new value
sysenv # show all environment properties
jvm # show jvm info
keymap # show keymap
sc # show classes loaded in jvm
sc javax.servlet.Filter
sc -d javax.servlet.Filter
sc *StringUtils
sm # show methods in class
sm java.math.RoundingMode
sm -d java.math.RoundingMode
sm java.math.RoundingMode <init>
jad com.example.demo.arthas.user.UserController
ognl
ognl '@java.lang.System@out.println("hello ognl")' # 此时第一个Terminal会输出'hello ognl'
sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash\
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader @com.example.demo.arthas.user.UserController@logger
ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
watch com.example.demo.arthas.user.UserController * '{params, throwExp}' # 监控请求参数,需要在浏览器端发起请求。
thread # show all thread
thread tid # show thread with id
thread -n 3 # show top 3 usage
thread -n 3 -i 5000 # show cpu usage in latest 5 second
thread -b # show blocking

也可以使用thread -n 3命令打印出CPU占比最高的前三个线程,这差不多是top -Hp & printf & jstack 三令合一的效果了

ArthasHotSwap (idea插件)

修改文件内容(建议是添加打印日志,不要添加新方法/属性等变动大的内容)后,单击右键 maven编译 -> swap this class -> 热部署命令已经复制到粘贴板 -> 登录远程服务器(需要提前关闭已启动的arthas进程)粘贴并执行热部署命令(此时尽量只有一个java进程) -> 热部署成功 - 动重新启动arthas

问题:内网下怎么使用ArthasHotSwap?

热部署时会把修改后的字节码内容发送到阿里云0ss中,内网环境无法访问。将.sh文件下载到本地即可。

一个完整命令如下:

sudo echo "curl -L http://xxxtai-arthas-hot-swap.oss-cn-beijing.aliyuncs.com/public/xxx  > HotSwapScript4OneClass.sh ;
echo 'yyyy  HotSwapScript4OneClass.sh' > HotSwapScript4OneClass.md5sum;
md5sum --status -c ./HotSwapScript4OneClass.md5sum;
if [[ \$? -eq 0 ]]; then
    chmod +x HotSwapScript4OneClass.sh;
    yes | ./HotSwapScript4OneClass.sh  zzzz wwww;
else
    echo 'It is necessary to report this error to xxxtai@163.com!!!';
fi" > ArthasHotSwapMD5Check.sh; chmod +x ./ArthasHotSwapMD5Check.sh; ./ArthasHotSwapMD5Check.sh;

可知会得到如下文件:

  • HotSwapScript4OneClass.sh
  • HotSwapScript4OneClass.md5sum
  • ArthasHotSwapMD5Check.sh

把.sh中curl命令都提前下载好对应的文件。

use in docker

若docker镜像无法联网,就不要使用arthas-boot.jar。
将arthas-bin.zip (约12M,下载地址)或解压后挂载到容器中,进入容器即可访问arthas。

arthas-tunnel-server & arthas-spring-boot-starter

  • copy following dependency to pom.xml
<dependency>
    <groupId>com.taobao.arthas</groupId>
    <artifactId>arthas-spring-boot-starter</artifactId>
    <version>3.3.9</version>
</dependency>

then copy following to application.yml

arthas:
  agent-id: abcdefg
  tunnel-server: 'ws://127.0.0.1:7777/ws'

agent-id will be used later.

then run springboot application

watch com.xxx.controller.ToolController ping '{params, target, returnObj}'
watch com.xxx.controller.ToolController ping '{params[0], target, returnObj}'

异步任务

后台/异步运行一个任务
watch org.springframework.web.servlet.DispatcherServlet getHandler returnObj >> d:/tmp/arthas-log.txt &
查看所有任务
jobs
删除任务,JOB_ID由jobs命令展示
kill $JOB_ID

实战

Arthas实践:是哪个Controller处理了请求?

来源:https://hengyun.tech/arthas-springmvc-controller/

  • 运行App
  • 运行 arthas java -jar arthas-boot.jar
    • trace org.springframework.web.servlet.DispatcherServlet doDispatch
    • 发送请求 curl http://me:60001/users
    • watch org.springframework.web.servlet.DispatcherServlet getHandler returnObj
    • 发送请求 curl http://me:60001/users

见附件【附件】springboot-find-exact-executing-controller-by-arthas.zip

查看类的静态属性

getstatic demo.MathGame random

查看内存里某个变量的值

sc -d *ValuetodaysSsoProperties
vmtool --action getInstances --className cn.valuetodays.project.webapp.eblog.web.ValuetodaysSsoProperties --limit 10
vmtool --action getInstances --className cn.valuetodays.project.webapp.eblog.web.ValuetodaysSsoProperties --express 'instances[0]'
vmtool --action getInstances --className cn.valuetodays.project.webapp.eblog.web.ValuetodaysSsoProperties --express 'instances[0].clientId'

使用

thread -n 3 占用cpu高的前3个线程

有时候我们发现应用卡住了, 这可能是因为发生了死锁或者其他锁等待问题。 为了排查这类问题, arthas提供了thread -b, 一键找出那个罪魁祸首。

注意, 目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。

trace 某个方法调用链路是什么和执行耗时是多少?

  • trace com.simple.IndexController m –skipJDKMethod false
  • trace com.simple.IndexController m

sm com.intellij.execution.rmi.RemoteServer

sc -d -f com.intellij.execution.rmi.RemoteServer

ognl @com.intellij.execution.rmi.RemoteServer"">'@com.intellij.execution.rmi.RemoteServer@SERVER_HOSTNAME

getstatic com.intellij.execution.rmi.RemoteServer SERVER_HOSTNAME

ognl @com.intellij.execution.rmi.RemoteServer"">'@com.intellij.execution.rmi.RemoteServer@SERVER_HOSTNAME.length()’

referer:

作者:张三  创建时间:2022-04-19 19:41
最后编辑:张三  更新时间:2025-11-13 16:46