点击上方“Java基基”,选择“设为星标”
做积极的人,而不是积极废人!
每天 14:00 更新文章,每天掉亿点点头发...
源码精品专栏
原创 | Java 2021 超神之路,很肝~
中文详细注释的开源项目
RPC 框架 Dubbo 源码解析
网络应用框架 Netty 源码解析
消息中间件 RocketMQ 源码解析
数据库中间件 Sharding-JDBC 和 MyCAT 源码解析
作业调度中间件 Elastic-Job 源码解析
分布式事务中间件 TCC-Transaction 源码解析
Eureka 和 Hystrix 源码解析
Java 并发源码
来源:juejin.cn/post/
7021725088659701791
一、初识Arthas
1.使用前:日志满天下
2.使用后:一个能打的都没有
二、kotlin/jvm 也能用
三、必备知识
1.启动Arthas
2.启动过程示意
3.探针Javaagent
4.“代价”
四、Arthas的命令分类
1.信息的观测&监控
2.我想改变程序行为
3.基础使用命令和日志处理命令
五、温馨提示
1.表达式是可以调用静态方法的
2.命令中使用到类名时,一般都是要使用全限定名的
3.分布式下的Arthas
4.关闭Arthas
5.重新连接Arthas
6.永远记得使用help
写在最后
一、初识Arthas
说起来,第一次接触Arthas不是因为我正需要用到它(因为我压根就不知道能有这种能力的工具),而是朋友的推荐,当我了解它拥有的能力之后,我震惊了,世上竟有如此powerful的东西。如果你是初次接触Arthas,那么恭喜你,你发现了宝藏。
1.使用前:日志满天下
以前,我们排查问题最常用的方法就是日志:
这个方法报错了,参数传了啥?打日志
这个if为啥没进去?打两条日志
这个方法执行了多少次?循环打日志
请求耗时很慢,那个环节比较慢?花式打日志 当线上出现问题的时候,也是通过日志来定位,比较尴尬的是,日志加上去,发版,服务就需要重启,这样会导致一些问题:
一是对服务有影响,该时刻请求会被中断,进而失败(当时没有摘流量这种操作)
二是重启后问题现场已经被破坏了,无法复现问题
三是日志过多,落盘会导致io升高,磁盘容量需求也变高,日志查询速度也变慢
四是加一次日志往往还不能定位到问题,需要加几次
❝
实践中发现,遇到的许多问题,如果能打日志时能遵循日志规范,是能够轻松定位的,但往往在团队开发中,从日志规范->规范日志,是一个艰巨的,持续性的任务.
❞
2.使用后:一个能打的都没有
可以不太恰当地说,熟练使用Arthas就像在线上开了Debug一样,甚至在某些方面比Debug更加便捷和强大。
想看方法的调用信息?Easy
依赖包混乱,不知道实际运行用了哪个?So Easy
怀疑线程在摸鱼?Very Easy
热更新代码?比较麻烦,但可以
❝
当你线上遇到问题无从下手时,也可以做一下类比:这个问题,如果你能打断点,那你会怎么操作?这个操作能否用Arthas命令实现?
❞
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
二、kotlin/jvm 也能用
随着kotlin的使用越来越广泛,Arthas能否用于kotlin也是一个值得思考的问题。kotlin编译之后跟java一样也是class文件,而Arthas是运行于jvm中的,主要功能也是通过对增强字节码来实现的,因此源码是kotlin的小伙伴也是适用的,美中不足的是,涉及到字节码反编译的时候,会跟kotlin的源码差异较大,会看到一些以kotlin开头的包名和方法(kotlin的语法糖实现类),不像java的那么直白。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud
视频教程:https://doc.iocoder.cn/video/
三、必备知识
❝
https://arthas.aliyun.com/doc/quick-start.html
有很详尽的说明,此处仅是简单说明❞
1.启动Arthas
//首先下载 arthas-boot.jar 启动程序,下边是通过curl来下载,也可以浏览器直接访问该链接下载
curl -O https://arthas.aliyun.com/arthas-boot.jar
//直接执行该启动jar包即可,启动后会提示选择需要“Debug”的jvm进程,
java -jar arthas-boot.jar
//也可以直接通过 ps -ef 等命令找到jvm进程的pid(如下方的 3425),然后添加到末尾,这样可以直接关联jvm进程,不需要选择
java -jar arthas-boot.jar 3425
2.启动过程示意
简单示意,想详细了解的小伙伴可以看Arthas的https://github.com/alibaba/arthas
通过jvm的机制,可以使正在运行的应用去加载指定的代码,并且拥有更改字节码的能力
Arthas是区分client和server的,client独立运行,server依附在宿主应用上
❝
由此也可以衍生出一个使用Arthas的思路,假设你能够让正在运行的应用执行指定代码,或者添加代码到已有逻辑里边,那你会怎么利用这个特性解决你遇到的问题
❞
3.探针Javaagent
如果说对javaagent有印象的话,那一定是java的Debug了,因为要开启Debug,是需要在启动参数中加入agent的,如 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5001
限于篇幅原因,agent技术不在此展开,可以自行了解,目前只要明确其可以更改正在运行类的字节码即可,从而对程序进行观测和影响。
部分的小伙伴可能会提到,为何不利用jvm的机制直接加载Debug的agent呢?
首先,有试过一下,但是attach失败了,推测是该agent只能启动时候进行指定;
其次,Debug其实对性能损耗是比较大的,尤其是断点很多的时候;
再者,在线上的宿主机或者容器临时开启一个端口,不知道运维大佬会不会放过你;
4.“代价”
对于所在企业内部尚未应用Arthas到生产环境的小伙伴而言,想要尝试使用那必定是要知悉其中风险滴,下边我们简要分析下:
首先,你并不是第一个吃螃蟹的人,Arthas至今已经迭代了多个版本(阿里团队研发),并且很多知名企业都在使用。
其次,由前文的启动示意可知,Arthas实际上就是运行在目标宿主jvm上的,因此一般也只会影响该jvm。
再次,如果目标jvm的内存配置很小,那有可能会attach失败,或者由于频繁更新字节码,导致gc。
最后,需要注意对宿主机的影响,当你把多个jvm进程启动在一个宿主机上时,如果使用Arthas的jvm出现快速写盘(如Arthas日志输出到文件,或者更改了日志级别)时,有可能导致宿主机io负载过高,cpu也是如此。
四、Arthas的命令分类
初步接触Arthas的时候,容易被其强大的功能和命令冲昏头脑,导致实际遇到问题时候,不知所措,所以初学者应当对功能和命令进行分类,以便梳理和记忆。以下是本人对命令的理解和分类:(每个命令都可点击跳转到官方使用文档)
1.信息的观测&监控
a.观测具体的类、方法【重点】
b.查看运行的状态&信息
2.我想改变程序行为
3.基础使用命令和日志处理命令
此部分命令较为简单直接,参阅官方文档即可
五、温馨提示
❝
强烈推荐阅读Github Arthas上的 user-case:
https://github.com/alibaba/arthas/issues?q=label%3Auser-case
❞
1.表达式是可以调用静态方法的
经过简单的了解,我们都知道,Arthas的部分命令(【观测被动执行的方法】)是支持表达式的,表达式中除了预定义的几个参数外,也可以调用静态方法获取结果,进而执行其它操作。
a.使用 TraceId or Flow or Cookie 来过滤请求
在实践中,为了把单个请求的日志串联起来,往往会生成一个标识,有的称之为traceId,有的称之为流水flow,而这些标识往往都是可以通过静态方法来获取的,因此,只要所使用的系统中,具备客户端指定标识的能力时,我们就能在服务端准确地观测该请求。如,在springboot搭建的web项目中,就可以这样获取cookie @org.springframework.web.context.request.RequestContextHolder@getRequestAttributes().getRequest().getCookies()
2.命令中使用到类名时,一般都是要使用全限定名的
在使用 watch trace 等命令的时候,是需要指定类名和方法名的, 如
watch com.wingli.controller.DemoController demoMethod
在使用 ognl 表达式的时候也是一样,如
ognl '@java.lang.System@out.println("hello")'
3.分布式下的Arthas
因为Arthas的使用对象是单个jvm进程,当你的应用是分布式的,并且使用的系统不具备将请求导向某台制定机子的时候,要想捕捉这个请求,则需要多个应用都启用Arthas,然后一个一个去执行对应的观测命令
4.关闭Arthas
如果所在的系统不是让Arthas常驻宿主应用,那么每次使用前都要进行启动,每次使用完都是需要进行关闭的,否则Arthas常驻jvm会消耗一定的资源,涉及的命令有
quit 退出本次连接,但宿主jvm内仍运行着arthas-server,只是退出了arthas-client
stop 退出arthas-server,并恢复增强过的类
5.重新连接Arthas
当因为某些原因退出了 arthas-client 的时候,也可以通过 telnet ip port 来连接上 arthas-server ,而没必要再次attach。
6.永远记得使用help
Arthas相关命令的help都写得很详细易懂,当你忘记了参数时,它可以帮助你
写在最后
Arthas目前应用广泛,相关的使用文章也非常多,并且官方也有收集整理使用案例,因此就不再重复写命令的使用和案例了。此文主要目的是简单了解Arthas能力的来源,以及提供Arthas命令的分类方式,为尚不熟练的小伙伴提供思路,以至于遇到问题不必浏览一次所有命令,再确认有没有自己想要的!
Arthas最好的学习资料就是官网上的上百个使用case,以及官网的在线教程!
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:
已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)