Dubbo 服务导出过程

Dubbo 服务导出过程

dubbo采用 URL 作为配置信息的统一格式,所有扩展点都通过传递 URL 携带配置信息,通过上一篇文章:

dubbo源码实现之SPI 和自适应扩展点 中我们可以了解到dubbo是如何确保扩展点一定可以获取到url的

URL 是 Dubbo 配置的载体,通过 URL 可让 Dubbo 的各种配置在各个模块之间传递

如下是一个使用dubbo协议发布服务的url:

dubbo://192.168.99.1:20880/com.gupaoedu.dubbo.ISayHelloService?anyhost=true&application=springboot-dubbo-provider
&bean.name=ServiceBean:com.gupaoedu.dubbo.ISayHelloService&bind.ip=192.168.99.1&bind.port=20880&cluster=failsafe&deprecated=false&dubbo=2.0.2
&dynamic=true&generic=false&interface=com.gupaoedu.dubbo.ISayHelloService&methods=sayHello&pid=21932&qos-enable=false&register=true&release=2.7.2
&side=provider&timeout=50000&timestamp=1582010821966

 

起点:

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

 

流程概述:组装url --》 导出服务 --》 注册服务

整个逻辑大致可分为三个部分

(1)第一部分是前置工作,主要用于检查参数,组装 URL

(2)第二部分是导出服务,包含导出服务到本地 (JVM),和导出服务到远程两个过程

(3)第三部分是不同的协议实例向注册中心注册服务,用于服务发现(例如dubbo协议会去zookeeper上注册一个节点)

注意:导出服务到远程包括导出服务(不是导出到本地)和注册服务两个步骤

为什么发布远程服务需要两步呢?

首先我们需要明白注册中心的功能是什么,注册中心只是一个记录,一个用于记录有哪些ip地址和端口提供了哪些服务的记录中心,其不会承担和客户端进行通信和提供服务的功能

也就是说我们想要发布一个远程服务给客户端调用,注册中心只是负责提供服务端的门牌号的功能,具体的通信还是需要服务端自己来做,什么意思呢?

就是说服务端和客户端的网络IO操作还是服务端进行维护的,而dubbo默认是使用netty来实现远程通信的,因此导出远程服务的作用实际上就是利用Netty的远程通信能力,来打开一个端口等待接收来自客户端的请求

 

源码分析:

服务导出的入口方法是 ServiceBean 的 onApplicationEvent。onApplicationEvent 是一个事件响应方法,该方法会响应Spring 容器刷新事件,在收到 Spring 上下文刷新事件后执行服务导出操作

ServiceBean 是 Dubbo 与 Spring 框架进行整合的关键,可以看做是两个框架之间的桥梁。具有同样作用的类还有 ReferenceBean

关键类:

RegistryProtocol :此类的作用是将协议url注册到注册中心

protocol的export()方法被调用之前,会经过什么呢?

当一个protocol的export()方法被调用之前,会首先经过其包装类的层层方法,在这些包装类中执行一系列的操作之后才会调用到真正的protocol的export()方法,如下所示:

如图所示:

(1)首先会经过Protocol$Adaptive的export方法,在其中会解析url中的protocol参数的值,然后从IOC容器中找到真正的protocol(被QoSProtocolWrapper包装的protocol)

(2)然后经过QoSProtocolWrapper的export()方法,QoSProtocolWrapper用于给运维人员添加操作的空间

(3)经过 ProtocolFilterWrapper的export()方法,ProtocolFilterWrapper是protocol拦截器链上的一个拦截器

 

服务的发布做了哪些事情

1.基于spring进行解析配置文件存储到ServiceConfig

2.各种判断逻辑,保证配置信息安全性

3.组装url(registry:// --> zookeeper:// --> dubbo:// --> injvm://)

4.构建一个invoker(动态代理)

5.RegistryProtocol.export()(注册服务到注册中心)

6.各种wrapper(Protocol$Adapter、filterWrapper,QosProtocolWrapper,listener)

7.DubboProtocol.export()发布服务,创建ExchangeServer ,调用bind()方法,进入Transporters 的bind方法,默认是NettyTransporter(使用Netty进行底层通信)

8.启动一个NettyServer(这里就接上了netty的内容,具体就是使用主从reactor线程模型来处理客户端的请求)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章