首先,将arthas-boot.jar工具下载到你本地,我的是windows,随便放到一个目录当中,例如——
文章插图
接着,直接在运行着Dubbo消费端进程的IDEA上打开Terminal——
文章插图
然后,输入 java -jar C:Users92493Downloads12229238_garthas-boot.jar,arthas正常运行成功话,将列出当前JVM上运行的进程——
文章插图
可以看到我们刚刚启动的provider进程与consumer进程,这时,只需要输入对应进程前面的编号【5】,就可以将Arthas 关联到启动类为 org.Apache.dubbo.demo.consumer.Application的 Java 进程上了——
文章插图
到这一步,我们就可以通过指令 sc *.proxy *模糊查询带有proxy标志的类名了,动态代理生成的类一般都是以Proxy标志——
文章插图
其中,这里的org.apache.dubbo.common.bytecode.proxy0就是消费者生成的动态代理类,我们可以直接反编译去查看它内部结构——
[arthas@57676]$ jad org.apache.dubbo.common.bytecode.proxy0
控制台就会打印出该动态代理类的内部结构——
/* * Decompiled with CFR. ** Could not load the following classes: * com.alibaba.dubbo.rpc.service.EchoService * org.apache.dubbo.common.bytecode.ClassGenerator$DC * org.apache.dubbo.demo.DemoService * org.apache.dubbo.rpc.service.Destroyable*/package org.apache.dubbo.common.bytecode;import com.alibaba.dubbo.rpc.service.EchoService;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.util.concurrent.CompletableFuture;import org.apache.dubbo.common.bytecode.ClassGenerator;import org.apache.dubbo.demo.DemoService;import org.apache.dubbo.rpc.service.Destroyable;public class proxy0 implements ClassGenerator.DC,Destroyable,EchoService,DemoService {public static Method[] methods;private InvocationHandler handler;public String sayHello(String string) {Object[] objectArray = new Object[]{string};Object object = this.handler.invoke(this, methods[0], objectArray);return (String)object;}public CompletableFuture sayHelloAsync(String string) {Object[] objectArray = new Object[]{string};Object object = this.handler.invoke(this, methods[1], objectArray);return (CompletableFuture)object;}public Object $echo(Object object) {Object[] objectArray = new Object[]{object};Object object2 = this.handler.invoke(this, methods[2], objectArray);return object2;}public void $destroy() {Object[] objectArray = new Object[]{};Object object = this.handler.invoke(this, methods[3], objectArray);}public proxy0() {}public proxy0(InvocationHandler invocationHandler) {this.handler = invocationHandler;}}
在Dubbo案例当中,当我们执行 String message = service.sayHello("dubbo")去调用远程接口时,其实是调用了动态代理生成的方法——public String sayHello(String string) {Object[] objectArray = new Object[]{string};Object object = this.handler.invoke(this, methods[0], objectArray);return (String)object;}
举一反三,这个Arthas工具类可以在线上生产环境查看一些我们新部署的代码,看是否是新改动的 。作者:朱季谦
出处:
https://www.cnblogs.com/zhujiqian/p/16114954.html
推荐阅读
- Java JVM启动参数大全
- 14个Java并发容器,你用过几个?
- JavaScript 中对于Promise的理解
- JAVA快速入门——算数运算符
- Java I/O 入门篇
- 深入理解Java继承的实现原理
- Java-背包算法实现
- JavaScript 中的位运算和权限设计
- JAVA中ArrayList、LinkedList、Vector、Stack的比较
- javascript 类型的隐式转换