<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
閱讀Dubbo原始碼過程中,會發現,Dubbo消費端在做遠端呼叫時,預設通過 Javassist 框架為服務介面生成動態代理類,呼叫javassist框架下的JavassistProxyFactory類的getProxy(Invoker invoker, Class<?>[] interfaces)方法,動態生成一個存放在JVM中的動態代理類。
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) { return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)); }
那麼,問題來了,如果我們想要一睹該動態生成的代理類內部結構是怎樣的,如何才能便捷做到的?
這就是我想介紹的一款工具,它可以幫助我們檢視JDK或者javassist生成的動態代理類,當然,它的功能遠不止此,還可以在生產環境進行診斷。
Arthas 是Alibaba開源的Java診斷工具,官方線上檔案地址:https://arthas.aliyun.com/doc/
根據官網上的介紹,它還可以解決以下問題————
當你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:
這個類從哪個 jar 包載入的?為什麼會報各種類相關的 Exception?
我改的程式碼為什麼沒有執行到?難道是我沒 commit?分支搞錯了?
遇到問題無法線上上 debug,難道只能通過加紀錄檔再重新發布嗎?
線上遇到某個使用者的資料處理有問題,但線上同樣無法 debug,線下無法重現!
是否有一個全域性視角來檢視系統的執行狀況?
有什麼辦法可以監控到JVM的實時執行狀態?
怎麼快速定位應用的熱點,生成火焰圖?
怎樣直接從JVM內查詢某個類的範例?
這些方案本文暫不展開,這裡只展開通過該工具檢視Dubbo生成的動態代理類。
我是直接在使用dubbo-parent原始碼中的例子,分別啟動了提供者與消費者。
首先,啟動提供者方法——
public class Application { public static void main(String[] args) throws Exception { startWithBootstrap(); } private static boolean isClassic(String[] args) { return args.length > 0 && "classic".equalsIgnoreCase(args[0]); } private static void startWithBootstrap() { ServiceConfig<DemoServiceImpl> service = new ServiceConfig<>(); service.setInterface(DemoService.class); service.setRef(new DemoServiceImpl()); DubboBootstrap bootstrap = DubboBootstrap.getInstance(); RegistryConfig registryConfig = new RegistryConfig("zookeeper://127.0.0.1:2181"); registryConfig.setTimeout(20000); ProtocolConfig protocolConfig = new ProtocolConfig(); protocolConfig.setName("dubbo"); protocolConfig.setHost("192.168.100.1"); protocolConfig.setPort(20877); bootstrap.application(new ApplicationConfig("dubbo-demo-api-provider")) .registry(registryConfig) .service(service) .protocol(protocolConfig) .start() .await(); } }
注意,需要設定RegistryConfig自己的zookeeper, protocolConfig.setHost("xxx.xxx.xxx.xxx")設定成你本地內網的ip即可;
DemoServiceImpl類詳情——
public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @Override public String sayHello(String name) { logger.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } public CompletableFuture<String> sayHelloAsync(String name) { return null; }
接著,啟動消費者,這裡可以設定一個休眠時間,這樣就可以一直維持消費者執行在記憶體當中——
public class Application { public static void main(String[] args) { runWithRefer(); } private static void runWithRefer() { RegistryConfig registryConfig = new RegistryConfig("zookeeper://127.0.0.1:2181"); registryConfig.setTimeout(30000); ProtocolConfig protocolConfig = new ProtocolConfig(); protocolConfig.setName("dubbo"); protocolConfig.setHost("192.168.200.1"); protocolConfig.setPort(20899); ReferenceConfig<DemoService> reference = new ReferenceConfig<>(); reference.setApplication(new ApplicationConfig("dubbo-demo-api-consumer")); reference.setRegistry(registryConfig); reference.setInterface(DemoService.class); DemoService service = reference.get(); String message = service.sayHello("dubbo"); System.out.println("列印了5555555"+message); try { Thread.sleep(100000000); } catch (InterruptedException e) { e.printStackTrace(); } }
當Dubbo的服務提供者與消費者都正常執行時,說明此時JVM虛擬機器器記憶體裡已經存在動態生成的代理類,這時,我們就可以開始通過arthas-boot.jar工具進行檢視了。
首先,將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工具類可以線上上生產環境檢視一些我們新部署的程式碼,看是否是新改動的。
到此這篇關於Alibaba Java診斷工具Arthas檢視Dubbo動態代理類的文章就介紹到這了,更多相關Alibaba Java診斷工具Arthas內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45