手记

Arthas 诊断工具集成与使用

阿尔萨斯(Arthas)是阿⾥巴巴开源的⼀款多功能诊断⼯具,⽬前⻛靡全世界,在业界⾮常出名,是阿⾥巴巴现有开源项目中star数最多的项⽬。⽤户⽂档在:arthas.aliyun.com/doc/index.html 它使⽤起来比较简单,但是如果在容器环境或者云上开发,会有些不便,比如:下载和运⾏。因此使⽤arthas-tunnel-server的形式(C/S模式),可以极⼤的简化对它的使用。

搭建ATS(arthas-tunnel-server)

目前搭建ats的工作已经完成,这⾥是介绍在项⽬中(以及容器环境下)如何搭建的ats。建⽴应⽤arthas-ops,应⽤中,仅放置了Dockerfile以及启动脚本entrypoint.sh。Dockerfile如下:

FROM registry-vpc.cn-hangzhou-finance.aliyuncs.com/linkebase/openjdk8:252

RUN useradd admin && usermod -aG sudo admin
RUN mkdir -p /home/admin/ && chown -R admin:admin /home/admin
RUN wget -c "https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-tunnel-server/3.5.0/arthas-tunnel-server-3.5.0-fatjar.jar" -O /home/admin/arthas-tunnel-server.jar

COPY ./entrypoint.sh /home/admin/entrypoint.sh
RUN chmod +x /home/admin/entrypoint.sh

WORKDIR /home/admin
USER admin

EXPOSE 8080


ENTRYPOINT ["sh","-c", "/home/admin/entrypoint.sh"]

启动脚本entrypoint.sh:

echo "application starting..."
CAFE_ENV_DC_NAME=`env|grep CAFE_ENV_DC_NAME| cut -d= -f2-`
CAFE_ENV_CELL_NAME=`env|grep CAFE_ENV_CELL_NAME| cut -d= -f2-`
CAFE_ENV_ZMODE=`env|grep CAFE_ENV_ZMODE| cut -d= -f2-`
JAVA_OPTS=""
if [ -n "$CAFE_ENV_DC_NAME" ]; then
JAVA_OPTS="$JAVA_OPTS -Dcom.alipay.ldc.datacenter=${CAFE_ENV_DC_NAME} "
fi
if [ -n "$CAFE_ENV_CELL_NAME" ]; then
JAVA_OPTS="$JAVA_OPTS -Dcom.alipay.ldc.zone=${CAFE_ENV_CELL_NAME} "
fi
if [ -n "$CAFE_ENV_ZMODE" ]; then
JAVA_OPTS="$JAVA_OPTS -Dzmode=${CAFE_ENV_ZMODE} "
fi

JVM_OPTS="-Xms$(( $(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1024 / 1024 * 45 / 100))m -Xmx$(( $(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1024 / 1024 * 45 / 100))m -Xmn$(( $(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1024 / 1024 * 45 / 100 * 3 / 8))m -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=256M -Xss256K -XX:MaxDirectMemorySize=$(( $(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1024 / 1024 * 45 / 100 * 85 / 100))m -Xloggc:/home/admin/logs/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/logs -XX:ErrorFile=/home/admin/logs/hs_err_pid%p.log"
java ${JVM_OPTS} ${JAVA_OPTS} -jar -Duser.timezone=GMT+08 -Djava.security.egd=file:/dev/./urandom /home/admin/arthas-tunnel-server.jar

echo "application start successfully..."

可以看到脚本就是启动⼀下arthas-tunnel-server.jar这个springboot的 fatjar。通过LinkE构建镜像,创建应⽤服务,然后部署之,⼀般单台ats就可以了,多台还需要⾃⼰解决分布式会话问题,有些麻烦。
这⾥可以得到应用服务的ip是:10.253.109.211。访问 http://10.253.109.211:8080/ ,可以看到如下界面:

这表示ats已经准备就绪,可以⽤它连接需要诊断的机器了。

集成Arthas

创建好的ats只是⼀个提供了管控endpoint的服务,它⽬前不会有作⽤,但是我们需要知道它的ip,因为我们的应⽤会连接到ats。
有多种⽅式可以连接到ats进⾏操作,比如:登录上容器,运⾏⼀堆脚本,下载agent,然后连上去,在控制台页面操作,如果你重新部署了应⽤,那么。。。就再重复⼀遍。
这⾥推荐使⽤springboot-starter的形式,⼀劳永逸的解决这个问题。下⾯以诊断greenwich-ops这个应⽤为例,介绍如何在应⽤中集成arthas,过程非常简单,看完后,只需要30秒。

引入starter

根层pom引入arthas客户端的springboot-starter,目前版本是:3.5.3

<dependency>
	<groupId>com.taobao.arthas</groupId>
	<artifactId>arthas-spring-boot-starter</artifactId>
	<version>${arthas.version}</version>
</dependency>	

如果遇到非技术性因素引入不到,可以直接用此 arthas-spring-boot-starter-3.5.3.jar pan.baidu.com/s/1IOC13O5pcnUaXks_rManYw 包(提取码:aewx),推到maven仓库即可。

然后在各个模块中声明dependency依赖。

<dependency>
	<groupId>com.taobao.arthas</groupId>
	<artifactId>arthas-spring-boot-starter</artifactId>
</dependency>	

应用配置

由于应用要连接ats,那么就需要知道ats的ip地址,同时也要给予ats⼀个标示信息,告知自己是谁。在application.yml中增加配置:

# arthas
arthas:
  agent-id: greenwich-ops-abcdefg
  tunnel-server: ws://10.253.109.211:7777/ws

其中:

  • arthas.agent-id 是表示⾃⼰是谁,因为ats要求不能重复,所以推荐是:应⽤名-任意字符,只需要唯⼀标示这个应⽤即可,不要照抄示例;
  • arthas.tunnel-server 是表示ats的地址,其中ip是arthas-ops应⽤服务的ip,当前开发环境的ip是10.253.109.211,端⼝默认7777。

集成完毕,提交代码,发布即可。

演示诊断

greenwich-ops的在开发环境的应⽤服务,其中⼀台机器的ip是:10.253.109.211。我们在这个应⽤上已经完成了集成,并已经发布。接下来,演示arthas诊断的⼀⼩部分功能,⾄于全部功能自行学习。

访问 http://10.253.109.211:8080,输⼊需要诊断机器的ip、端⼝以及agent-id,如下:

点击【Connect】,会展现⼀下界⾯:

这代表你已经成功的连接到需要诊断的机器上。

观察函数出入参

有时我们需要在运⾏时环境,观察传⼊的参数和返回的结果。⼀般会打印⽇志,但是如果你集成了arthas,就完全不需要了。
Arthas使⽤watch命令,对⽅法进行观测。
我们看⼀下greenwich-ops应用中的⼀段代码:

ResourceReadManagerImpl为例,如果我们想观察queryResourceList这个⽅法的⽤户请求⼊参以及响应,我们可以在控制台输⼊如下命令:

watch com.aliyun.fsi.insurance.greenwich.ops.service.manager.impl.ResourceReadManagerImpl queryResourceList "{params,returnObj}" -x 3

其中详细解释见:arthas.aliyun.com/doc/watch.html

然后访问页面,调用应用的接口,然后在arthas-ops界面可以看到如下输入:

其中红色框中,代表着输入:greenwich-ops.switcher,这个是输⼊的⼊参内容。绿色框中,代表着输出,是⼀个资源列表List,其中有两个元素,如框中所示。通过使用watch命令,可以⾮常容易的观测接口调用的输⼊参数,当然可以增加⼀些条件规则来选择性的输入调用内容,这个需要你自行研究,我不再赘述。
Arthas使用trace命令,对⽅法进行跟踪。
我们看⼀下greenwich-ops应用中的⼀段代码:

对于ResourceAdd这个Controller,action⽅法的实现,可以看到调⽤了resourceCreateManager和resourceReadManager两个成员变量的⽅法,我们可以看看它们各⾃的耗时。我们可以在控制台输入如下命令:

trace com.aliyun.fsi.insurance.greenwich.ops.web.controller.ResourceAdd action '#cost > 10'

其中详细解释见:arthas.aliyun.com/doc/trace.html

然后访问页面,调用应用的接⼝,然后在arthas-ops界⾯可以看到如下输入:

其中红⾊框中,调用ResourceAdd的action⽅法,执行过程中的调用方法输出。其中该⽅法中,最耗时的子⽅法被红⾊展示,当前场景中,就是ResourceCreateManager#registerResource⽅法,它耗时3.47ms。

通过使用trace命令,可以非常容易的找寻到性能的瓶颈,哪些方法执行的慢,慢在哪里,可以通过不断的增加trace命令来对⼦⽅法进⾏更进⼀步的追踪,这个需要你自行研究,我不再赘述。

1人推荐
随时随地看视频
慕课网APP