ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

dubbo的服务发布

2021-02-15 16:57:47  阅读:236  来源: 互联网

标签:dubbo 服务 spring 接口 发布 Invoker apache org


本篇了解一下dubbo的服务发布流程

一. 从配置文件走起

在这里插入图片描述
这个xml文件是dubbo提供的一个demo,用过dubbo的同学应该都了解这就是暴露一个接口demoService,那么这个接口如何暴露出去的呢?
既然是配置了这个xml就能暴露出去,那么肯定是从xml文件的配置开始,上图圈出来的红框中,很明显看出来是用的schema定义的xml文件,不了解的同学可以百度一下:schema自定义配置这个关键词,了解下schema自定义配置相关知识,这里就不再讲了,提供一个参考链接:https://www.cnblogs.com/jifeng/archive/2011/09/14/2176599.html
那么了解了schema自定义配置之后,就可以找到关于

<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>

这行代码具体怎么开始了
在这里插入图片描述
在这里插入图片描述
上面这两个图表示了service标签的定义
在这里插入图片描述
org.apache.dubbo.config.spring.schema.DubboNamespaceHandler#init中可以看到对service标签的解析器:new DubboBeanDefinitionParser(ServiceBean.class, true),所以我们进入org.apache.dubbo.config.spring.ServiceBean里面查看源码

二. ServiceBean

查看ServiceBean源码
在这里插入图片描述
上面这些实现的接口都是spring的接口,其实主要作用就是保存了spring容器的引用,并且监听了spring容器的启动事件,再看看ServiceBean的关系图
在这里插入图片描述
ServiceBean中有一个方法
在这里插入图片描述
他会发出一个Export事件
在这里插入图片描述
在这里插入图片描述
从注释可以发现是调用了org.apache.dubbo.config.spring.ServiceBean#exported,这个方法在上面截图有了,里面调用了父类的org.apache.dubbo.config.ServiceConfig#exported在这里插入图片描述
可以看到依旧是发布了一个事件,这个事件点进去看:
在这里插入图片描述
实际是走到了org.apache.dubbo.config.ServiceConfig#export
在这里插入图片描述
上面这里和dubbo老版本的区别很大,都走了事件发布和监听,比较绕,我也没理解太懂,不用管太多,只要找到org.apache.dubbo.config.ServiceConfig#export这里,其实是真正开始发布服务,我们重点关注里面的方法:org.apache.dubbo.config.ServiceConfig#doExport
在这里插入图片描述
doExportUrls方法中,首先是加载配置文件中dubbo.registry.address的注册中心信息并组装到registryURLs,然后下面是一个for循环,这个循环的protocols是代表通信协议,for循环表示一个服务可以有多个通信协议,比如tcp、http,默认是dubbo的tcp协议
然后进入:org.apache.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol这个方法,这个代码很多,前面都是各种校验和组装信息
在这里插入图片描述
重点在这里,可以看到注释写的是暴露本地服务和暴露远程服务,本地服务指的就是本地服务JVM里面的服务,不用通过zookeeper进行远程网络通信调用;那么远程服务就是通过zookeeper网络通信调用,暴露给可以给其他服务调用,这个应该不难理解
那么我们来看暴露本地服务的流程:
在这里插入图片描述
首先PROTOCOLPROXY_FACTORY分别都是从SPI中获取的,getAdaptiveExtension说明是获取的是个自适应的扩展类,那么分别看org.apache.dubbo.rpc.Protocolorg.apache.dubbo.rpc.ProxyFactory,这两个接口的@Adaptive注解都是标注在接口上,说明是动态生成的扩展类(这块是SPI的知识,不了解的可以看我之前的文章:dubbo的SPI)
在这里插入图片描述
其中ProxyFactory的作用就是为了获取一个接口的代理类,例如获取一个远程接口的代理。
ProxyFactory有2个方法,

  1. getInvoker:针对server端,将服务对象,如DemoServiceImpl包装成一个Invoker对象。
  2. getProxy :针对client端,创建接口的代理对象,例如DemoService的接口。

然后Protocol的默认实现是@SPI("dubbo")-> org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol
ProxyFactory的默认实现是@SPI("javassist")->org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory
回到org.apache.dubbo.config.ServiceConfig#exportLocal方法中,看方法调用PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, local),其实调用的就是org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory#getInvoker
在这里插入图片描述
进入这个方法,首先看到是获取一个Wrapper,这个wrapper是从org.apache.dubbo.common.bytecode.Wrapper#makeWrapper里面获取来的,那么这个Wrapper的作用其实是类似springBeanWrapper的,spring 的BeanWrapper作用是:
BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性
那么dubbo的Wrapper其实和他差不多,在dubbo里面它的作用也是:包装一个接口或者类,可以通过Wrapper对接口或者类的实例进行取值、赋值、或者制定方法的调用
回到代码中,拿到这个Wrapper包装类之后,new AbstractProxyInvoker<T>(proxy, type, url)创建了一个Invoker这个Invoker它是一个可执行的对象,能够根据方法的名称、参数得到相应的执行结果,它里面有一个很重要的方法:org.apache.dubbo.rpc.Invoker#invoke(Invocation invocation),这个方法的入参Invocation代表了要执行的方法和参数等重要信息,Invoker在dubbo里面相当的重要,这里先说一下概念:
Invoker有3种类型的Invoker

  1. 本地执行类的Invoker
    server端:要执行 demoService.sayHello,就通过InjvmExporter来进行反射执行demoService.sayHello就可以了。

  2. 远程通信类的Invoker
    client端:要执行 demoService.sayHello,它封装了DubboInvoker进行远程通信,发送要执行的接口给server端。
    server端:采用了AbstractProxyInvoker执行了DemoServiceImpl.sayHello,然后将执行结果返回发送给client.

  3. 多个远程通信执行类的Invoker聚合成集群版的Invoker
    client端:要执行 demoService.sayHello,就要通过AbstractClusterInvoker来进行负载均衡,DubboInvoker进行远程通信,发送要执行的接口给server端。
    server端:采用了AbstractProxyInvoker执行了DemoServiceImpl.sayHello,然后将执行结果返回发送给client.

标签:dubbo,服务,spring,接口,发布,Invoker,apache,org
来源: https://blog.csdn.net/qq_34203492/article/details/113815530

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有