Next.js+React+Node零碎实战,搞定SSR服务器渲染内附文档源码下载地址:百度网盘Java 诊断工具 Arthas-实操案例实操案例排查函数调用异样通过curl 请求接口只能看到返回异样,然而看不到具体的请求参数和堆栈信息。shell@Alicloud:~$ curl{"timestamp":1655435063042,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}复制代码查看UserController的 参数/异样在Arthas里执行:watch com.example.demo.arthas.user.UserController * '{params, throwExp}'复制代码
第一个参数是类名,反对通配第二个参数是函数名,反对通配 拜访watch命令会打印调用的参数和异样再次通过curl 调用可能在arthas外面查看到具体的异样信息。把获取到的后果开展,可能用-x参数:watch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2复制代码返回值表达式在下面的例子里,第三个参数是返回值表达式,它实际上是一个ognl表达式,它反对一些内置对象:
loaderclazzmethodtargetparamsreturnObjthrowExpisBeforeisThrowisReturn
比如返回一个数组:watch com.example.demo.arthas.user.UserController * '{params[0], target, returnObj}'复制代码条件表达式watch命令反对在第4个参数里写条件表达式,比如:当拜访 user/1 时,watch命令没有输入当拜访 user/101 时,watch会打印出后果。
当异样时捕捉watch命令反对-e选项,示意只捕捉抛出异样时的请求:watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e复制代码按照耗时进行过滤watch命令反对按请求耗时进行过滤,比如:watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'复制代码热更新代码这个也是真的秀。
拜访 http://localhost:61000/user/0 ,会返回500异样:shell@Alicloud:~$ curl http://localhost:61000/user/0{"timestamp":1655436218020,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}复制代码通过热更新代码,修改这个逻辑。jad反编译UserControllerjad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java复制代码jad反编译的后果保存在 /tmp/UserController.java文件里了。再打开一个Terminal 窗口,而后用vim来编辑/tmp/UserController.java:vim /tmp/UserController.java复制代码比如当 user id 小于1时,也失常返回,不抛出异样:@GetMapping(value={"/user/{id}"})public User findUserById(@PathVariable Integer id) {
logger.info("id: {}", (Object)id);if (id != null && id < 1) { return new User(id, "name" + id); // throw new IllegalArgumentException("id < 1");}return new User(id.intValue(), "name" + id);}复制代码sc查找加载UserController的ClassLoader[arthas@1266]$ sc -d *UserController | grep classLoaderHash classLoaderHash 19469ea2复制代码classLoaderHash 是19469ea2,前面需要使用它。mc保存好/tmp/UserController.java之后,使用mc(Memory Compiler)命令来编译,并且通过-c或者--classLoaderClass参数指定ClassLoader:
...