一文带你整合arthas和springboot
背景
前面我们在一文带你快速上手arthas中分享了arthas的基本使用,请大家花两分钟回忆一下我们当时是怎么使用arthas的。

现在公布答案,我们当时是这么使用arthas的:
- 将arhtas的安装包下载到本地
- 在arthas-boot.jar所在的目录执行
java -jar arthas-boot.jar连接本地的java程序,进入到arthas的终端 - 在arthas终端执行各种指令获取java程序中的信息
不知道大家看出来没有,arthas作为一个工具只能调试本地的程序,如果我们想使用arthas调试远程服务器上的java程序,就需要将arhtas的安装包上传到远程服务器,然后再执行arthas指令进行调试。
现在的问题是:自动有了docker简化项目的部署后,目前绝大部分公司的应用都是运行在docker容器中,所以如果我们想要调试docker容器中的java程序,还需要将arhtas给复制到docker容器中,然后我们每次调试都要进入到应用的容器内部执行arthas指令,这样做是不是有点繁琐呢?
而且我们的应用基本上都是集群部署的,一个应用通常会部署到多个服务器上的docker容器中,如果我们需要进入很多个容器进行arthas调试,那这也太麻烦了。有什么有什么好的办法可以简化这个过程呢?
请大家花2分钟想想有没有什么好的办法解决这个问题,我们希望使用arthas调试远程服务器上的程序能够更简单一些,不想做将arthas复制到docker容器中,以及进入到应用的容器中去执行arthas指令这种繁琐的事情。
实际上arthas的开发者也考虑到了这点,并且提供了解决方案。接下来我们看下他是如何解决这个问题的。
将arthas整合到springboot项目中
为了让arthas的用户更加方便的在服务器上通过arthas调试java程序,arthas的开发者想出了一个办法:“让每个springboot项目随身携带一个arthas”
具体做法是:在springboot项目中引入arthas的starter,将arhtas绑定到用户的springboot程序中,在用户启动springboot项目的同时,也同时启动arhtas-boot,并且直接attach用户的springboot程序。最后通过暴露arhtas终端的端口的方式,方便用户随时进入到arthas的终端进行调试。
这样做的好处就是用户不需要再去arthas的官网下载arthas的安装包了,也不需要将arthas的安装包拷贝到应用容器中了,只需要在springboot项目中引入一个arthas starter即可。这样也就解决了我们前面提到的问题。
下面我带大家将整个过程操作一遍,来对比这种方式和我们之前使用arthas方式的区别。
在springboot项目中引入arthas-starter
首先我们需要在项目中引入arthas-starter,如下所示:
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>${arthas-spring-boot-starter.version}</version>
</dependency>
然后在application.yml中配置arthas终端的端口暴露
arthas:
telnet-port: 3658 # Telnet 连接端口,用于通过 Telnet 客户端连接 Arthas
http-port: 8563 # HTTP 服务端口,用于通过浏览器访问 Arthas Web Console
简单说下这两个端口暴露是干嘛的:
- telnet-port: 暴露这个端口是为了支持用户通过telnet的方式进入arhtas的终端进行远程调试。
- http-port:暴露这个端口则是为了支持用户通过浏览器的方式进入到arhtas的终端进行远程调试。
下面我们就来验证这两种不同的进入到arhtas终端的方式
进入到arthas的终端
首先我们需要启动项目,如下图所示:

从控制台的日志中,我们可以看到arthas也启动了,接下来我们需要进入到arthas终端进行代码调试。
通过telnet进入arhtas终端
前面在配置文件中配置了telnet-port: 3658,也就是说我们使用telnet需要通过3658的端口来进入arthas终端。如下图所示:

当我们执行telnet localhost 3658指令后就会进入到arthas的终端,后面该做什么相信大家应该知道了,我们在之前的一文带你快速上手arthas中分享过,我们可以在arthas终端执行各种arthas指令调试代码,如下图所示:

通过telnet进入到arthas终端的方式我们就讲完了,整个过程不需要像之前那样从官网下载arhtas的安装包,然后执行java -java arthas-boot.jar的指令进入到arhtas终端。现在我们将arhtas整合进springboot项目中后,直接一个telnet指令就可以直接进入到终端,比之前的方式简单多了,也快多了!
下面我们来讲下如何通过浏览器进入到arhtas终端
通过浏览器进入arhtas终端
前面在配置文件中配置了http-port: 8563,也就是说我们需要通过浏览器的8563端口进入到arthas终端,下面我们来试试:

从上图我们可以看到当我们在浏览器中输入http://localhost:8563后就直接进入到了arhtas的终端,是不是很方便?这就是将arhtas整合进springboot项目后的好处!
到这里我们就讲完了两种进入arthas终端的方式,现在的问题是:我们刚才是在自己本地电脑上启动的springboot应用,而我们使用arhtas更多的是为了解决测试和生产环境中的问题,所以刚才我们使用arthas的方式不具有代表性。
接下来我们需要将这个springboot项目部署到远程服务器上,然后再使用arthas进行远程调试,只有这样才能原汁原味的还原我们在工作中使用arthas-starter解决问题的过程。
使用arthas-springboot远程调试
将项目部署到远程服务器上
这里我是使用docker部署的,下面是我写的Dockerfile用来构建容器镜像:
# 使用 OpenJDK 8 作为基础镜像
FROM openjdk:8-jdk
# 设置工作目录
WORKDIR /app
# 将打包好的 JAR 文件复制到容器中
COPY target/arthas-demo-*.jar /app/arthas-demo.jar
# 暴露应用运行的端口,根据 application.yml 配置为 8401
EXPOSE 8401
# 启动 Java 应用
ENTRYPOINT ["java", "-jar", "arthas-demo.jar"]
下面是我用于启动springboot容器应用的docker-compose.yml
services:
arthas-demo:
# 容器名称
container_name: arthas-demo
# 构建当前目录下的 Dockerfile
build: .
# 暴露端口,格式为 宿主机端口:容器端口
ports:
- "8401:8401"
- "3658:3658"
- "8563:8563"
# 重启策略
restart: always
由于我们这次需要使用本地的浏览器访问远程的arthas,因此需要开启arthas的远程访问,同时为了保证连接的安全,咱们最好还要给arthas添加权限认证,具体做法是:在application.yml中添加如下配置:

接下来就是打包,上传jar包,Dockfile,以及docker-compose.yml到远程服务器上。
然后在远程服务器上执行docker-compose up启动项目。
使用浏览器访问远程的arthas
上面已经做好了所有准备工作,接下来咱们使用浏览器看看是否能进入arthas终端。第一次连接需要输入账号密码,也就是咱们前面在配置文件中配置的用户名和密码,如下图所示:

输入后,即可进入到arthas终端,如下图所示:

除了使用浏览器外,咱们还可以使用telnet终端来访问远程的arthas,这个我们在前面也讲过,如下图所示:

使用telnet进入到arthas终端需要使用auth指令进行权限认证,否则执行arthas指令会报没有权限的提示。

关于将arhtas整合到springboot项目中,我们就讲完了,下面盘点下我在写这篇文章的过程中所踩过的坑,希望能对各位朋友有所启发!
部署arthas踩过的坑
最后顺便分享下我在写这篇文章时踩过的一些坑以及自己是如何解决的,希望这能帮你在使用arthas时遇到问题时提供一些可能的解决方案。
坑一:openjdk:8-jdk-alpine导致arthas启动报错
我一开始使用的镜像是openjdk:8-jdk-alpine,结果启动的时候会报错,报错记录大致是跟arthas有关的bean无法注册啥的,我也不知道为啥会这样。
我尝试问了AI,然后也也尝试了AI给出的所有建议,但是都没什么卵用,无奈之下,我决定去arthas的GitHub的issue那里看看有没有哪个倒霉蛋碰到了和我同样的问题,结果还真让我找到了,幸运的是有好心人恰好就对这个问题给出了解决方案。
具体的解决办法就是不要使用alpine版的jdk镜像,于是我顺着这条建议将Dockerfile中的镜像从openjdk:8-jdk-alpine改成了openjdk:8-jdk,然后再重新使用docker compose部署,结果没想到奇迹真的出现了,没有再出现arthas报错的日志提示了!
这件事给我的启发是:当自己碰到无法搞定的问题时,可以多去看看GitHub的issue,毕竟该工具的用户那么多,大概率会有人踩过这个坑,所以我也大概率能够在这里找到解决方案。
坑二:本地启动可以使用浏览器进入arhtas终端,但是远程部署就连不上了
我遇到的第2个比较难搞的问题是:当我在本地启动springboot应用时,通过浏览器访问arhtas的http端口,可以直接进入到arthas终端。但是当我将项目达成jar包部署到远程服务器上的docker容器后,再去使用浏览器访问远程服务器上的arhtas,结果发现始终连不上,但是看容器的日志又没有任何报错信息。
我一开始还以为是防火墙的问题,所以我将云服务器的防火墙给关了,结果还是连不上arhtas。我想不明白为什么会这样,于是我去问AI,结果AI给出了几个行不通的建议,我尝试无果。ε=(´ο`*)))唉,宝宝心里苦啊。
然后我决定上网谷歌一番,然后在一篇文章的提示下,我突然来了灵感,决定为arhtas开启远程访问的权限,因为我之前连接远程服务器上的redis时,也需要修改redis的配置文件,将ip_adress改成0.0.0.0,同时还要为redis设置密码,如果不这样做使无法使用本地的redis客户端工具连上远程的redis的。
我想arthas很可能也是借鉴了类似的设计,那就是使用localhost访问的时候不需要开启远程访问,但是部署到Linux服务器上后,我们再去访问arthas就需要设置ip为0.0.0.0来开启远程访问了。
所以,我最终添加了如下配置:
arthas:
ip: 0.0.0.0 # 监听的 IP 地址,0.0.0.0 表示监听所有 IP 地址
username: admin
password: 123123
然后重新打包部署启动,没想到还真就解决了无法连上远程arthas的问题。
文章中完整示例代码的地址

最后的总结
这篇文章中我们分享了如何让arthas的使用更简单的方法,那就是将arthas整合到springboot项目中,这样做的好处是我们不再需要做将arhtas的安装包拷贝到容器中等一系列繁琐的事情,而是可以直接通过浏览器访问远程服务器上的arthas进行远程调试。
实际上我们还有一个问题没有解决,那就是我们的应用是集群部署的,如果每个服务器都有一个arthas,那样一个个去访问每个服务器上的arthas终端有点麻烦,我们希望通过一个统一的入口访问集群上任意一个服务节点上的arthas终端,至于如何实现这点,咱们下篇文章再见!
觉得有收获的朋友可以点个赞,您的鼓励就是我最大的动力!
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)