likes
comments
collection
share

Dubbo源码|十六、Dubbo服务暴露—容器启动

作者站长头像
站长
· 阅读数 14

开篇

本文主要介绍Dubbo服务暴露过程——根据URL来启动对应的容器。

Dubbo服务暴露(一)

Dubbo服务暴露(二)

Dubbo服务暴露(三)

Dubbo服务暴露(四)

导出URL

doExportUrlsFor1Protocol方法主要是为每一个协议导出对应的URL,由于该方法太长了,就只截取一部分吧。

Dubbo源码|十六、Dubbo服务暴露—容器启动

该方法的主要工作如下:

  1. 获取协议名称,如果为空,设置为dubbo协议。
  2. 设置sideprovider
  3. 设置运行时参数,dubbo版本、时间戳、协议版本等。
  4. 将监控、应用、模块、提供者、协议、服务本身、元数据、接口方法、方法参数等信息放入map中。
  5. 如果是泛化服务,设置泛化服务相关信息。
  6. 根据服务接口找到对应的Wrapper类,拿到Wrapper类中所有的方法名字,放入map。
  7. 获取token配置,放入map,token可以在一定程度上防止人为调用dubbo服务。
  8. 将map中的信息放入服务元数据的attachments中。
  9. 获取hostport并构造URL
  10. 通过DubboSPI获取ConfiguratorFactory的实现类,该步骤可以可以对URL的内容进行更改或做一些定制化操作。
  11. 根据scope来判断是本地注册还是注册到注册中心,如果是none则不进行导出,如果是local代表导出到本地,仅供本地JVM调用,但是也是会走完整的dubbo流程的。
  12. 将服务的元数据信息放、到元数据中心。
  13. 通过代理工厂生成Invoker,并进行服务导出。

来看下这一步生成URL的格式,协议头已经换成dubbo,这个URL将被注册到注册中心上去,同样的,如果消费者拿到这个URL也可以直接调用的。

dubbo://172.17.0.157:20880/org.apache.dubbo.demo.DemoService?anyhost=true&application=dubbo-demo-annotation-provider&bind.ip=172.17.0.157&bind.port=20880&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello,sayHelloAsync&pid=87628&release=&service.name=ServiceBean:/org.apache.dubbo.demo.DemoService&side=provider&timestamp=1670995605316

根据协议导出

Exporter<?> exporter = PROTOCOL.export(wrapperInvoker);

PROTOCOL是一个自适应扩展对象,之前讲过自适应扩展类的方法需要有URL参数或者参数的类里有getURL方法,那么wrapperInvoker里面的URL长什么样呢?由于太长了,省略一部分:

registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?xxxx

这个URL的协议头为registry,所以实际调用的方法为RegistryProtocol#export

Dubbo源码|十六、Dubbo服务暴露—容器启动

该方法根据originInvoker获取注册中心的URL(格式为registry://xxx?xx=xx&registry=zookeeper)以及提供者的URL(格式为dubbo://172.17.0.157:20880/org.apache.dubbo.demo.DemoService?xxxx)。

根据服务提供者URL生成一个overrideSubscribeUrl,该URL协议为provider://,在服务提供者URL的基础上增加参数category=configurators&check=falseoverrideSubscribeUrl为老Dubbo版本的动态配置监听URL。

根据providerUrlregistryUrl对参数进行简化,因为有些参数是没用的,没有必要放到注册中心,比如:monitorbind.ipbind.port等,简化后生成要注册的URL,并注册到注册中心。

启动容器

调用doLocalExport方法,根据协议来启动具体的容器。

Dubbo源码|十六、Dubbo服务暴露—容器启动

protocol.export会根据方法参数中getURL的返回值,根据协议来确定调用哪个类,这里最终会调用到DubboProtocol#export方法,在这个方法中会启动NettyTomcat等具体容器。

Dubbo源码|十六、Dubbo服务暴露—容器启动

该方法主要工作过程如下:

  1. 根据URL获取服务Key一般为接口类名。
  2. 构造一个DubboExporter,并放入缓存。
  3. 开启Netty服务。
  4. 根据Invoker中配置的optimizer参数获取扩展的自定义序列化处理类。

开启服务openServer

Dubbo源码|十六、Dubbo服务暴露—容器启动

该方法先获取服务地址(ip:port),判断是否创建过服务,创建过的话直接进行reset,没有的话,则创建服务容器。

创建服务createServer

Dubbo源码|十六、Dubbo服务暴露—容器启动

  1. 根据传进来的URL生成服务URL,该URL比原来新增加了channel.readonly.sent=TRUEheartbeat=60000codec=dubbo参数。
  2. 从URL中获取协议的服务器端实现类型,例如:dubbo协议的mina、netty等,http协议的jetty、tomcat等,默认为netty协议。
  3. 把创建好的Server进行返回。

启动Netty

Dubbo源码|十六、Dubbo服务暴露—容器启动

最终会调用到NettyServer类中的doOpen方法,设置Netty相关参数进行绑定启动Netty。

后记

本文主要介绍Dubbo服务暴露过程——根据URL来启动对应的容器,下一篇将进行介绍是如何把URL注册到注册中心里去的。