2018-09-19 21:17:37 +08:00
|
|
|
|
|
|
|
|
|
|
2018-09-17 22:21:49 +08:00
|
|
|
|
## Arthas
|
|
|
|
|
|
|
|
|
|
![arthas](site/src/site/sphinx/arthas.png)
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
English version goes [here](README.md).
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
`Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
当你遇到以下类似问题而束手无策时,`Arthas`可以帮助你解决:
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
0. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
|
|
|
|
|
0. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
|
|
|
|
|
0. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
|
|
|
|
|
0. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
|
|
|
|
|
0. 是否有一个全局视角来查看系统的运行状况?
|
|
|
|
|
0. 有什么办法可以监控到JVM的实时运行状态?
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
`Arthas`采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
### 快速开始
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
#### Linux/Unix/Mac
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
安装Arthas:
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
curl -L https://alibaba.github.io/arthas/install.sh | sh
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
启动Arthas:
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
./as.sh
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Windows
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
1. 点击 [这里](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) 下载最新的Arthas zip包
|
|
|
|
|
2. 解压缩zip包.
|
|
|
|
|
3. 进入bin目录
|
|
|
|
|
4. 执行以下命令 `as.bat $PID`
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
### 文档
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
社区正在进行英文版本的翻译工作,如果您有兴趣请在 [这里](https://github.com/alibaba/arthas/issues/51)留言。
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
* [用户文档](https://alibaba.github.io/arthas/)
|
|
|
|
|
* [安装](https://alibaba.github.io/arthas/install-detail.html)
|
|
|
|
|
* [快速入门](https://alibaba.github.io/arthas/quick-start.html)
|
|
|
|
|
* [进阶使用](https://alibaba.github.io/arthas/advanced-use.html)
|
2018-09-17 22:21:49 +08:00
|
|
|
|
* [Questions and answers](https://github.com/alibaba/arthas/labels/question-answered)
|
2018-09-19 21:17:37 +08:00
|
|
|
|
* [参与贡献](https://github.com/alibaba/arthas/blob/master/CONTRIBUTING.md)
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
### 案例展示
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
2018-09-17 22:27:50 +08:00
|
|
|
|
#### Dashboard
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
|
|
|
|
* https://alibaba.github.io/arthas/dashboard
|
|
|
|
|
|
|
|
|
|
![dashboard](site/src/site/sphinx/_static/dashboard.png)
|
|
|
|
|
|
2018-09-18 10:46:54 +08:00
|
|
|
|
#### Thread
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
一目了然的了解系统的状态,哪些线程比较占cpu?他们到底在做什么?
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ thread -n 3
|
|
|
|
|
"as-command-execute-daemon" Id=29 cpuUsage=75% RUNNABLE
|
|
|
|
|
at sun.management.ThreadImpl.dumpThreads0(Native Method)
|
|
|
|
|
at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
|
|
|
|
|
at com.taobao.arthas.core.command.monitor200.ThreadCommand$1.action(ThreadCommand.java:58)
|
|
|
|
|
at com.taobao.arthas.core.command.handler.AbstractCommandHandler.execute(AbstractCommandHandler.java:238)
|
|
|
|
|
at com.taobao.arthas.core.command.handler.DefaultCommandHandler.handleCommand(DefaultCommandHandler.java:67)
|
|
|
|
|
at com.taobao.arthas.core.server.ArthasServer$4.run(ArthasServer.java:276)
|
|
|
|
|
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
|
|
|
|
|
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
|
|
|
|
|
at java.lang.Thread.run(Thread.java:745)
|
|
|
|
|
|
|
|
|
|
Number of locked synchronizers = 1
|
|
|
|
|
- java.util.concurrent.ThreadPoolExecutor$Worker@6cd0b6f8
|
|
|
|
|
|
|
|
|
|
"as-session-expire-daemon" Id=25 cpuUsage=24% TIMED_WAITING
|
|
|
|
|
at java.lang.Thread.sleep(Native Method)
|
|
|
|
|
at com.taobao.arthas.core.server.DefaultSessionManager$2.run(DefaultSessionManager.java:85)
|
|
|
|
|
|
|
|
|
|
"Reference Handler" Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference$Lock@69ba0f27
|
|
|
|
|
at java.lang.Object.wait(Native Method)
|
|
|
|
|
- waiting on java.lang.ref.Reference$Lock@69ba0f27
|
|
|
|
|
at java.lang.Object.wait(Object.java:503)
|
|
|
|
|
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### jad
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
对类进行反编译:
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
$ jad javax.servlet.Servlet
|
|
|
|
|
|
|
|
|
|
ClassLoader:
|
|
|
|
|
+-java.net.URLClassLoader@6108b2d7
|
|
|
|
|
+-sun.misc.Launcher$AppClassLoader@18b4aac2
|
|
|
|
|
+-sun.misc.Launcher$ExtClassLoader@1ddf84b8
|
|
|
|
|
|
|
|
|
|
Location:
|
|
|
|
|
/Users/xxx/work/test/lib/servlet-api.jar
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Decompiled with CFR 0_122.
|
|
|
|
|
*/
|
|
|
|
|
package javax.servlet;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import javax.servlet.ServletConfig;
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
|
|
import javax.servlet.ServletRequest;
|
|
|
|
|
import javax.servlet.ServletResponse;
|
|
|
|
|
|
|
|
|
|
public interface Servlet {
|
|
|
|
|
public void init(ServletConfig var1) throws ServletException;
|
|
|
|
|
|
|
|
|
|
public ServletConfig getServletConfig();
|
|
|
|
|
|
|
|
|
|
public void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
|
|
|
|
|
|
|
|
|
|
public String getServletInfo();
|
|
|
|
|
|
|
|
|
|
public void destroy();
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### sc
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
查找JVM中已经加载的类
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ sc -d org.springframework.web.context.support.XmlWebApplicationContext
|
|
|
|
|
class-info org.springframework.web.context.support.XmlWebApplicationContext
|
|
|
|
|
code-source /Users/xxx/work/test/WEB-INF/lib/spring-web-3.2.11.RELEASE.jar
|
|
|
|
|
name org.springframework.web.context.support.XmlWebApplicationContext
|
|
|
|
|
isInterface false
|
|
|
|
|
isAnnotation false
|
|
|
|
|
isEnum false
|
|
|
|
|
isAnonymousClass false
|
|
|
|
|
isArray false
|
|
|
|
|
isLocalClass false
|
|
|
|
|
isMemberClass false
|
|
|
|
|
isPrimitive false
|
|
|
|
|
isSynthetic false
|
|
|
|
|
simple-name XmlWebApplicationContext
|
|
|
|
|
modifier public
|
|
|
|
|
annotation
|
|
|
|
|
interfaces
|
|
|
|
|
super-class +-org.springframework.web.context.support.AbstractRefreshableWebApplicationContext
|
|
|
|
|
+-org.springframework.context.support.AbstractRefreshableConfigApplicationContext
|
|
|
|
|
+-org.springframework.context.support.AbstractRefreshableApplicationContext
|
|
|
|
|
+-org.springframework.context.support.AbstractApplicationContext
|
|
|
|
|
+-org.springframework.core.io.DefaultResourceLoader
|
|
|
|
|
+-java.lang.Object
|
|
|
|
|
class-loader +-org.apache.catalina.loader.ParallelWebappClassLoader
|
|
|
|
|
+-java.net.URLClassLoader@6108b2d7
|
|
|
|
|
+-sun.misc.Launcher$AppClassLoader@18b4aac2
|
|
|
|
|
+-sun.misc.Launcher$ExtClassLoader@1ddf84b8
|
|
|
|
|
classLoaderHash 25131501
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### stack
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
查看方法 `test.arthas.TestStack#doGet` 的调用堆栈:
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ stack test.arthas.TestStack doGet
|
|
|
|
|
Press Ctrl+C to abort.
|
|
|
|
|
Affect(class-cnt:1 , method-cnt:1) cost in 286 ms.
|
|
|
|
|
ts=2018-09-18 10:11:45;thread_name=http-bio-8080-exec-10;id=d9;is_daemon=true;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@25131501
|
|
|
|
|
@test.arthas.TestStack.doGet()
|
|
|
|
|
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
|
|
|
|
|
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
|
|
|
|
|
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
|
|
|
|
|
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
|
|
|
|
|
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
|
|
|
|
|
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
|
|
|
|
|
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
|
|
|
|
|
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
|
|
|
|
|
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
|
|
|
|
|
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
|
|
|
|
|
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
|
|
|
|
|
...
|
|
|
|
|
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
|
|
|
|
|
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
|
|
|
|
|
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
|
|
|
|
|
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:451)
|
|
|
|
|
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1121)
|
|
|
|
|
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
|
|
|
|
|
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
|
|
|
|
|
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
|
|
|
|
|
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
|
|
|
|
|
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
|
|
|
|
|
at java.lang.Thread.run(Thread.java:745)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Trace
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
观察方法执行的时候那个子调用比较慢:
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
![trace](site/src/site/sphinx/_static/trace.png)
|
|
|
|
|
|
|
|
|
|
#### Watch
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
观察方法 `test.arthas.TestWatch#doGet` 执行的入参,仅当方法抛出异常时才输出。
|
2018-09-18 10:46:54 +08:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ watch test.arthas.TestWatch doGet {params[0], throwExp} -e
|
|
|
|
|
Press Ctrl+C to abort.
|
|
|
|
|
Affect(class-cnt:1 , method-cnt:1) cost in 65 ms.
|
|
|
|
|
ts=2018-09-18 10:26:28;result=@ArrayList[
|
|
|
|
|
@RequestFacade[org.apache.catalina.connector.RequestFacade@79f922b2],
|
|
|
|
|
@NullPointerException[java.lang.NullPointerException],
|
|
|
|
|
]
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-20 09:52:38 +08:00
|
|
|
|
#### Monitor
|
|
|
|
|
|
|
|
|
|
监控某个特殊方法的调用统计数据,包括总调用次数,平均rt,成功率等信息,每隔5秒输出一次。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
$ monitor -c 5 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello
|
|
|
|
|
Press Ctrl+C to abort.
|
|
|
|
|
Affect(class-cnt:1 , method-cnt:1) cost in 109 ms.
|
|
|
|
|
timestamp class method total success fail avg-rt(ms) fail-rate
|
|
|
|
|
----------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
2018-09-20 09:45:32 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello 5 5 0 0.67 0.00%
|
|
|
|
|
|
|
|
|
|
timestamp class method total success fail avg-rt(ms) fail-rate
|
|
|
|
|
----------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
2018-09-20 09:45:37 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello 5 5 0 1.00 0.00%
|
|
|
|
|
|
|
|
|
|
timestamp class method total success fail avg-rt(ms) fail-rate
|
|
|
|
|
----------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
2018-09-20 09:45:42 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello 5 5 0 0.43 0.00%
|
|
|
|
|
```
|
|
|
|
|
|
2018-09-18 10:46:54 +08:00
|
|
|
|
#### Classloader
|
|
|
|
|
|
2018-09-19 21:17:37 +08:00
|
|
|
|
了解当前系统中有多少类加载器,以及每个加载器加载的类数量,帮助您判断是否有类加载器泄露。
|
|
|
|
|
|
2018-09-18 10:46:54 +08:00
|
|
|
|
```
|
|
|
|
|
$ classloader
|
|
|
|
|
name numberOfInstances loadedCountTotal
|
|
|
|
|
BootstrapClassLoader 1 3346
|
|
|
|
|
com.taobao.arthas.agent.ArthasClassloader 1 1262
|
|
|
|
|
java.net.URLClassLoader 2 1033
|
|
|
|
|
org.apache.catalina.loader.ParallelWebappClassLoader 1 628
|
|
|
|
|
sun.reflect.DelegatingClassLoader 166 166
|
|
|
|
|
sun.misc.Launcher$AppClassLoader 1 31
|
|
|
|
|
com.alibaba.fastjson.util.ASMClassLoader 6 15
|
|
|
|
|
sun.misc.Launcher$ExtClassLoader 1 7
|
|
|
|
|
org.jvnet.hk2.internal.DelegatingClassLoader 2 2
|
|
|
|
|
sun.reflect.misc.MethodUtil 1 1
|
|
|
|
|
```
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
2018-09-17 22:27:50 +08:00
|
|
|
|
#### Web Console
|
2018-09-17 22:21:49 +08:00
|
|
|
|
|
|
|
|
|
* https://alibaba.github.io/arthas/web-console
|
|
|
|
|
|
2018-09-18 10:46:54 +08:00
|
|
|
|
![web console](site/src/site/sphinx/_static/web-console-local.png)
|
2018-09-19 21:17:37 +08:00
|
|
|
|
|