Dubbo服务导出

一、简介

Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑

1、前置工作,主要用于检查参数,组装 URL。

2、导出服务,包含导出服务到本地 (JVM),和导出服务到远程两个过程。(根据服务参数,构造URL通过代理生成Inovker,在本地和远程导出得到一个Expoter对象)

3、向注册中心注册服务,用于服务发现。

二、导出流程图

服务导出流程:

1、接收到ContextRefreshedEvent刷新事件,调用ServiceBean.export,会执行ServiceConfig.export方法

2、从配置中心获取参数,检查一些参数配置

3、检查是否需要导出、是否配置延迟导出条件判断

4、调用doExport导出

5、调用doExportUrls,loadRegistries加在注册中心配置,构造URL集合,遍历所有注册协议调用doExportUrlsFor1Protocol为每个协议每个注册中心导出

6、得到服务的URL,把URL作为参数添加到registryURL中,然后JavassistProxyFactory生成Invoker代理,在调用协议导出得到一个Export

7、调用RegistryProtocol进行导出,主要分为根据对应协议导出,创建NettyServer;获取注册中心实现类ZookeeperRegistry,调用create方法创建持久/临时节点

8、服务导出后得到一个Exporter,添加到exporters集合中

9、发布服务导出事件ServiceBeanExportedEvent

三、DubboExport中的invoker是什么

一个服务导出后,会生成Export,Dubbo协议生成的是DubboExport。

  public DubboExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {
        super(invoker);
        this.key = key;
        this.exporterMap = exporterMap;
    }

当NettyServer接收到请求后,会根据请求中的服务信息,找到服务对应的DubboExporter对象,根据唯一serviceKey,从exporterMap得到DubboExporter对象,然后取出Invoker ,Invoker的结构:

ProtocolFilterWrapper$CallbackRegistrationInvoker:调用下层Invoker执⾏完之后,会遍历实现过滤器ListenableFilter的接口

ProtocolFilterWrapper$1:执行服务端的过滤器,执行完之后调用下层Invoker

RegistryProtocol$InvokerDelegate:服务委托类,调用下层Invoker

JavassistProxyFactory$1:包含Wrapper参数实现AbstractProxyInvoker的代理对象

Wrapper:Dubbo服务实现类的包装类

通过arthas工具命令可以看到生成的代理类

1、启动arthas,命令

java -jar arthas-boot.jar

2、选择对应序号,监控对应的服务

3、输入以下命令,可反编译去查看JavassistProxyFactory$1类

[arthas@14624]$ jad org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1
  package org.apache.dubbo.rpc.proxy.javassist;

       import org.apache.dubbo.common.URL;
       import org.apache.dubbo.common.bytecode.Wrapper;
       import org.apache.dubbo.rpc.proxy.AbstractProxyInvoker;

       class JavassistProxyFactory.1   extends AbstractProxyInvoker<T> {
           final Wrapper val$wrapper;

           JavassistProxyFactory.1(Object proxy, Class type, URL url, Wrapper wrapper) {
               this.val$wrapper = wrapper;
               super(proxy, type, url);
           }

           protected Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable {
/*58*/         return this.val$wrapper.invokeMethod(proxy, methodName, (Class[])parameterTypes, arguments);
           }
       }

输入以下,得到wrapper实现类,可以看到invokeMethod()方法中,有dubbo接口实现类,根据调用的方法名字和参数类型,调用具体实现方法

jad org.apache.dubbo.common.bytecode.Wrapper1
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 static Class[] mts1;
    
    .....无关方法省略..... 
    
    public Object invokeMethod(Object object, String string, Class[] classArray, Object[] objectArray) throws InvocationTargetException {
        //dubbo接口实现类
        DemoServiceImpl demoServiceImpl;
        try {
            demoServiceImpl = (DemoServiceImpl)object;
        }
        catch (Throwable throwable) {
            throw new IllegalArgumentException(throwable);
        }
        try {
            if ("sayHello".equals(string) && classArray.length == 1 && classArray[0].getName().equals("java.lang.String")) {
                return demoServiceImpl.sayHello((String)objectArray[0]);
            }
            if ("sayHello".equals(string) && classArray.length == 2 && classArray[0].getName().equals("java.lang.String") && classArray[1].getName().equals("java.lang.String")) {
                return demoServiceImpl.sayHello((String)objectArray[0], (String)objectArray[1]);
            }
        }
        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.DemoServiceImpl.").toString());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值