如果实在遇到上面的情况,在本地和测试都无法复现,那最常规的做法就是拉个线上分支的版本,增加一些调试日志,然后再重新发布版本进行调试。
在日常工作中我们经常会遇到一些线上异常的情况,而且有些问题只有在线上才会出现,由于环境和数据不一样在本地和测试环境根本没办法复现,而且线上也没有输出日志,那么遇到这种情况我们往往要怎么去解决呢?
常规做法
如果实在遇到上面的情况,在本地和测试都无法复现,那最常规的做法就是拉个线上分支的版本,增加一些调试日志,然后再重新发布版本进行调试。运气好加一次日志就可以找到问题,运气不好的话可能还要发布好几次才能定位到问题。
高级做法
下载安装 arthas
Arthas 是阿里开源的一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
上面的Arthas这款工具的官方介绍,从中我们可以看到这个工具可以查看方法的出入参,异常以及监测方法的耗时,我们排查问题的时候最重要的就是想知道一些方法的入参和返回,有了入参和返回的数据我们就可以模拟出具体的场景从而解决线上的问题。
注意这里说的方法不单单是外层的接口方法,任何Service层或者RPC层的方法都是可以的。之所以提出这一点是因为很多时候线上的接口都会有请求和结果的日志记录,但是并没有内部某个具体方法的入参和返回,而通过Arthas我们可以监控任何方法的入参和返回值。
我们可以在https://github.com/alibaba/arthas/releases 这个地址上下载具体的版本,下载下来就可以用,没什么难度。接下来阿粉通过一个案例来带大家使用一下 Arthas。
测试
首先我们启动一个Spring Boot应用,并且对外一个http的接口,具体的Controller和Service代码实现如下。
package com.example.demo.controller;
import com.example.demo.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping(value = "/hello")
public String hello(@RequestParam("name") String name) {
return helloService.sayHello(name);
}
}
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
public class HelloService {
public String sayHello(String name) {
String result = doSomething(name);
return "hello: " + result;
}
private String doSomething(String name) {
return name + " 欢迎关注 Java 极客技术";
}
}
上面的代码非常简单,对外暴露了一个 hello 接口,接收一个name参数,Service中通过sayHello方法,调用了一个内部的doSomething方法。其中过后我们访问 http://127.0.0.1:8080/hello?name=ziyou 可以看到如下的内容。
到这里都没什么问题,但是我们想象一下,如果在某些case doSomething的方法比较复杂,我们想知道在执行doSomething方法的时候具体的入参和返回值是什么,这个时候我们要怎么办呢?
当然如果采用上面的常规做法,增加一些日志,当然是可以,不过我们这里就来演示一下如何使用Arthas来实现这个效果。前面我们已经下载了Arthas了,下载完成后是一个压缩包,解压过后,可以通过命令java -jar arthas-boot.jar来启动Arthas。效果如下
可以看到启动过后Arthas会找到目前系统当中在运行的Java进程,我这里有四个进程,然后输入我们要监控的进程编号,这里是 4,然后回车,接下来我们就进入了Arthas的界面。
接下来我们使用Arthas的watch命令来监控入参和返回值,完整的命令如下:watch com.example.demo.service.HelloService doSomething '{params,returnObj}
接下来我们再去访问一下刚刚的接口,可以看到在终端上面有对应的数据输出。
简单解释一下对应的命令和输出的信息,watch是Arthas提供的命令,后面根据第一个参数是完整的类路径,第二个参数是我们要监控的方法名,第三个参数是一个表达是这里我们可以获取入参以及返回值或者异常等信息,对应的取值有params数组形式,可以通过params[0]来获取对应的属性,returnObj表示返回值,并且这两个都是可以通过.的形式,获取下面属性的值的。
watch命令后面的第三个参数其实是一个ognl表达式,如下所示我们是可以做一些计算和逻辑处理的,这就带来了很多高级的用法。Arthas的一些特殊用法文档说明 https://github.com/alibaba/arthas/issues/71
总结
Arthas除了watch之外还有很多其他的命令可以使用,比如trace可以统计每个方法执行的耗时,对于我们做一些性能优化有很大的帮助,还有比如支持热部署的功能等。完整的命令和使用方式大家可以在这个网址找到 https://arthas.aliyun.com/doc/,并且这里还提供了一套在线演示的功能,可以在在线教程中通过终端依次亲手执行每个命令来学习。官方提供了一个应用程序math-game.jar可以让我们在线调试,感兴趣的小伙伴可以去试一试。
©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经