Dubbo3实战-Dubbo与Arthas的使用

295 阅读1分钟

欢迎大家关注 github.com/hsfxuebao ,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈

1. arthas安装启动

1.1 安装

arthas.aliyun.com/doc/install…

1.2 启动

运行java -jar arthas-boot.jar 需要进入到arthas的解压目录中运行(否则会报错没有权限运行该jar),可以通过命令: find / -name arthas-boot.jar查找安装路径,如:/Users/**/.arthas/lib/3.4.0/arthas

image.png

2. 查看扩展接口适配器类的源码

[arthas@11050]$ jad org.apache.dubbo.rpc.Protocol$Adaptive
Affect(row-cnt:0) cost in 14 ms.
No class found for: org
[arthas@11050]$ jad org.apache.dubbo.rpc.Protocol$Adaptive

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@3541cb24

Location:
/Users/haoshaofei/IdeaProjects/dubbo-3.0/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/target/classes/

       /*
        * Decompiled with CFR.
        *
        * Could not load the following classes:
        *  org.apache.dubbo.common.URL
        *  org.apache.dubbo.common.extension.ExtensionLoader
        *  org.apache.dubbo.rpc.Exporter
        *  org.apache.dubbo.rpc.Invoker
        *  org.apache.dubbo.rpc.Protocol
        *  org.apache.dubbo.rpc.RpcException
        */
       package org.apache.dubbo.rpc;

       import java.util.List;
       import org.apache.dubbo.common.URL;
       import org.apache.dubbo.common.extension.ExtensionLoader;
       import org.apache.dubbo.rpc.Exporter;
       import org.apache.dubbo.rpc.Invoker;
       import org.apache.dubbo.rpc.Protocol;
       import org.apache.dubbo.rpc.RpcException;

       public class Protocol$Adaptive
       implements Protocol {
           public Exporter export(Invoker arg0) throws RpcException {
               String extName;
/*31*/         if (arg0 == null) {
                   throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
               }
/*32*/         if (arg0.getUrl() == null) {
                   throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");
               }
               URL url = arg0.getUrl();
/*35*/         String string = extName = url.getProtocol() == null ? "dubbo" : url.getProtocol();
/*36*/         if (extName == null) {
                   throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])");
               }
/*38*/         Protocol extension = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);
/*39*/         return extension.export(arg0);
           }

           public List getServers() {
               throw new UnsupportedOperationException("The method public default java.util.List org.apache.dubbo.rpc.Protocol.getServers() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
           }

           public void destroy() {
               throw new UnsupportedOperationException("The method public abstract void org.apache.dubbo.rpc.Protocol.destroy() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
           }

           public int getDefaultPort() {
               throw new UnsupportedOperationException("The method public abstract int org.apache.dubbo.rpc.Protocol.getDefaultPort() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
           }

           public Invoker refer(Class arg0, URL arg1) throws RpcException {
               String extName;
/*19*/         if (arg1 == null) {
                   throw new IllegalArgumentException("url == null");
               }
/*20*/         URL url = arg1;
/*21*/         String string = extName = url.getProtocol() == null ? "dubbo" : url.getProtocol();
/*22*/         if (extName == null) {
                   throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])");
               }
/*24*/         Protocol extension = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);
/*27*/         return extension.refer(arg0, arg1);
           }
       }

Affect(row-cnt:1) cost in 601 ms.

3. 查看服务提供端 Wrapper 类的源码

Dubbo 会给每个服务提供者的实现生成一个 Wrapper 类,在这个 Wrapper 类里最终是调用服务提供者的接口实现类, Wrapper 类的存在是为了减少反射的调用。那么我们可以使用 jad 命令方便地查看被包装后的某一个服务实现类,以便探究它是如何工作的。

为此,在启动 Dubbo 服务提供端和 Arthas 后,在 Arthas 的控制台执行下面的命令即可:

[arthas@11050]$ sc *Wrapper*
com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper
com.sun.org.apache.xerces.internal.util.EntityResolverWrapper
com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper
com.taobao.arthas.core.shell.handlers.term.CloseHandlerWrapper
org.apache.dubbo.common.bytecode.Wrapper
org.apache.dubbo.common.bytecode.Wrapper$$Lambda$145/1473981203
org.apache.dubbo.common.bytecode.Wrapper$$Lambda$146/1552326679
org.apache.dubbo.common.bytecode.Wrapper$$Lambda$147/1383519982
org.apache.dubbo.common.bytecode.Wrapper$1
org.apache.dubbo.common.bytecode.Wrapper0
org.apache.dubbo.common.bytecode.Wrapper1
org.apache.dubbo.common.bytecode.Wrapper2
org.apache.dubbo.common.bytecode.Wrapper3
org.apache.dubbo.common.extension.Wrapper
org.apache.dubbo.common.extension.support.WrapperComparator
org.apache.dubbo.common.extension.support.WrapperComparator$OrderInfo
...
[arthas@11050]$ jad org.apache.dubbo.common.bytecode.Wrapper1

ClassLoader:
+-sun.misc.Launcher$AppClassLoader@18b4aac2
  +-sun.misc.Launcher$ExtClassLoader@3541cb24

Location:
/Users/haoshaofei/IdeaProjects/dubbo-3.0/dubbo-common/target/classes/

/*
 * Decompiled with CFR.
 *
 * Could not load the following classes:
 *  org.apache.dubbo.common.bytecode.ClassGenerator$DC
 *  org.apache.dubbo.common.bytecode.NoSuchMethodException
 *  org.apache.dubbo.common.bytecode.NoSuchPropertyException
 *  org.apache.dubbo.common.bytecode.Wrapper
 *  org.apache.dubbo.demo.provider.GreetingServiceImpl
 */
package org.apache.dubbo.common.bytecode;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import org.apache.dubbo.common.bytecode.ClassGenerator;
import org.apache.dubbo.common.bytecode.NoSuchMethodException;
import org.apache.dubbo.common.bytecode.NoSuchPropertyException;
import org.apache.dubbo.common.bytecode.Wrapper;
import org.apache.dubbo.demo.provider.GreetingServiceImpl;

public class Wrapper1
extends Wrapper
implements ClassGenerator.DC {
    public static String[] pns;
    public static Map pts;
    public static String[] mns;
    public static String[] dmns;
    public static Class[] mts0;

    public Object invokeMethod(Object object, String string, Class[] classArray, Object[] objectArray) throws InvocationTargetException {
        GreetingServiceImpl greetingServiceImpl;
        try {
            greetingServiceImpl = (GreetingServiceImpl)object;
        }
        catch (Throwable throwable) {
            throw new IllegalArgumentException(throwable);
        }
        try {
            if ("hello".equals(string) && classArray.length == 0) {
                return greetingServiceImpl.hello();
            }
        }
        catch (Throwable throwable) {
            throw new InvocationTargetException(throwable);
        }
        throw new NoSuchMethodException(new StringBuffer().append("Not found method \"").append(string).append("\" in class org.apache.dubbo.demo.provider.GreetingServiceImpl.").toString());
    }

    public Class getPropertyType(String string) {
        return (Class)pts.get(string);
    }

    public String[] getPropertyNames() {
        return pns;
    }

    public Object getPropertyValue(Object object, String string) {
        try {
            GreetingServiceImpl greetingServiceImpl = (GreetingServiceImpl)object;
        }
        catch (Throwable throwable) {
            throw new IllegalArgumentException(throwable);
        }
        throw new NoSuchPropertyException(new StringBuffer().append("Not found property \"").append(string).append("\" field or getter method in class org.apache.dubbo.demo.provider.GreetingServiceImpl.").toString());
    }

    public void setPropertyValue(Object object, String string, Object object2) {
        try {
            GreetingServiceImpl greetingServiceImpl = (GreetingServiceImpl)object;
        }
        catch (Throwable throwable) {
            throw new IllegalArgumentException(throwable);
        }
        throw new NoSuchPropertyException(new StringBuffer().append("Not found property \"").append(string).append("\" field or setter method in class org.apache.dubbo.demo.provider.GreetingServiceImpl.").toString());
    }

    public String[] getMethodNames() {
        return mns;
    }

    public String[] getDeclaredMethodNames() {
        return dmns;
    }

    public boolean hasProperty(String string) {
        return pts.containsKey(string);
    }
}

Affect(row-cnt:1) cost in 231 ms.
[arthas@11050]$

参考文章

Dubbo3.0源码注释github地址
深度剖析Apache Dubbo核心技术内幕
dubbo源码系列
dubbo源码分析专栏