dubbo系列之服务发布-流程
先上两张经典图,大致了解一下发布流程
源码构成
dubbo-demo-provider.xml——注册文件
1 | <!-- 提供方应用信息,用于计算依赖关系 --> |
可以看到服务是通过dubbo的schema service进行注入的,那我们找到DubboNameSpaceHandler文件,即dubbo的命名空间处理器,找到dubbo:service标签解析行。
DubboNameSpaceHandler()
1 | public class DubboNamespaceHandler extends NamespaceHandlerSupport { |
ServiceBean类
ServiceBean类可以看到实现了ApplicationListener,这个接口就是spring的时间机制,看看ServiceBean继承这个接口实现的方法。
1 | public void onApplicationEvent(ApplicationEvent event) { |
export()
–>ServiceConfig.export()
-->doExport()
-->doExportUrls()
1 | private void doExportUrls() { |
doExportUrlsFor1Protocol()
1 | private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) { |
暴露本地服务和暴露远程服务的区别是什么?
1.暴露本地服务:指暴露在用一个JVM里面,不用通过调用zk来进行远程通信。例如:在同一个服务,自己调用自己的接口,就没必要进行网络IP连接来通信。
2.暴露远程服务:指暴露给远程客户端的IP和端口号,通过网络来实现通信。
本地暴露
exportLocal(url)
1 |
|
1 | Exporter<?> exporter = protocol.export( |
这句话是本地暴露的关键,看官方给的服务提供者暴露一个服务的详细过程,其实也就是这句代码
为了方便理解,介绍一下一些类和方法的概念:
proxyFactory
proxyFactory:就是为了获取一个接口的代理类,例如获取一个远程接口的代理。
它有2个方法,代表2个作用
a.getInvoker:针对server端,将服务对象,如DemoServiceImpl包装成一个Invoker对象。
b.getProxy :针对client端,创建接口的代理对象,例如DemoService的接口。
Wrapper
它类似spring的BeanWrapper,它就是包装了一个接口或一个类,可以通过wrapper对实例对象进行赋值 取值以及指定方法的调用。
Invoker
它是一个可执行的对象,能够根据方法的名称、参数得到相应的执行结果。
1 | 它里面有一个很重要的方法 Result invoke(Invocation invocation); |
Invocation
包含了需要执行的方法和参数等重要信息,目前它只有2个实现类RpcInvocation MockInvocation
它有3种类型的Invoker
1.本地执行类的Invoker
1 | 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.
Protocol
1.export:暴露远程服务(用于服务端),就是将proxyFactory.getInvoker创建的代理类 invoker对象,通过协议暴露给外部。
2.refer:引用远程服务(用于客户端), 通过proxyFactory.getProxy来创建远程的动态代理类,例如DemoService的远程动态接口。
exporter
维护invoder的生命周期。
exchanger
信息交换层,封装请求响应模式,同步转异步。
介绍完上面一些概念,接着看看本地暴露接下来的步骤,用一张清晰的图表示。
最终本地暴露的目的就是
1 | exporterMap.put(key, this)//key=com.alibaba.dubbo.demo.DemoService, this=InjvmExporter |
远程暴露
doExportUrlsFor1Protocol()
1 | //原理和本地暴露一样都是为了获取一个Invoker对象 |
远程暴露的关键就是invoker转换导exporter的过程
1 | -->proxyFactory.getInvoker//原理和本地暴露一样都是为了获取一个Invoker对象 |
———1.netty服务暴露的开始——- –>DubboProtocol.export
1 | -->serviceKey(url)//组装key=com.alibaba.dubbo.demo.DemoService:20880 |
——–2.信息交换层 exchanger 开始————–>Exchangers.bind(url, requestHandler)//exchaanger是一个信息交换层
1 | -->getExchanger(url) |
———3.网络传输层 transporter———————>Transporters.bind
1 | -->getTransporter() |
———4.打开断开,暴露netty服务——————————–>doOpen()
1 | -->设置 NioServerSocketChannelFactory boss worker的线程池 线程个数为3 |
还是贴一张图,理解更清晰一点
DubboProtocol()
1 | public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { |
参考链接