在应用编写好服务并进行之后,dubbo 负责将服务 export 出去,dubbo export 服务的时候主要做了以下几件事:
暴露服务的配置方式有:
以常用的 xml 配置为例,前面说了 dubbo 的 xml 自定义标签最后都是将对应的 bean 注入容器中,
- <dubbo:service interface="com.souche.service.TestDubboService" ref="testDubboServiceImpl"/>
dubbo 解析 xml 会将对应的 bean—ServiceBean 注入到 spring 容器中,由于解析 xml 的时候配置的 bean 是非 lazyInit 的,所以在 spring 容器初始化完成之后,会初始化所有非 lazyInit 的 bean。
在 spring 容器初始化后,会广播 ContextRefreshedEvent 事件通知,ServiceBean 实现了 ApplicationListener,在收到该事件之后调用 export 方法
- // AbstractApplicationContext
- public void refresh() throws BeansException,
- IllegalStateException {
- // Instantiate all remaining (non-lazy-init) singletons.
- finishBeanFactoryInitialization(beanFactory);
- // Last step: publish corresponding event.
- // 里面会广播ContextRefreshedEvent事件
- finishRefresh();
- }
- // ServiceBean
- public void onApplicationEvent(ApplicationEvent event) {
- // 在容器初始化完成之后收到ContextRefreshedEvent事件,开始export服务
- if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
- if (isDelay() && !isExported() && !isUnexported()) {
- if (logger.isInfoEnabled()) {
- logger.info("The service ready on spring started. service: " + getInterface());
- }
- export();
- }
- }
- }
服务 export 从 ServiceConfig#export 开始
如果 scope 没有配置或者配置 local、remote,dubbo 会将服务 export 到本地,意思就是:将服务以 injvm 协议 export 出去,如果是同一个 jvm 的应用可以直接通过 jvm 发起调用,而不需要通过网络发起远程调用。
export 到本地主要做了以下几件事:
如果 scope 没有配置或者配置 remote,dubbo 会创建 invoker,创建 invoker 的时候会启动 NettyServer,监听指定的端口等待 consumer 请求。在 dubbo 中 provider 和 consumer 端都会有 Invoker,实现的是同一个接口,但是不同的实现,invoker 的意义就是服务的代理,provider 侧的 invoker 就是提供服务的可执行体,在 netty 接收到请求之后会通过 invoker 来处理,最后调用目标服务。
创建 invoker 并启动 NettyServer 的调用堆栈
export 的主要过程是:
filter 和 listener 是可扩展的,可以自己实现 filter 和 listener,按照 SPI 方式配置好,dubbo 会自动加载。
前面只是完成 service 的启动并具备可被请求的状态,但是 dubbo 作为一个支持服务自发现的框架,还会把 provider 的信息注册到 registry,并且订阅 configurators。
注册的调用堆栈是
注册和订阅主要逻辑在 RegistryProtocol#export
registry 就是一个目录服务,注册的过程也就是创建对应的目录,并订阅关心的目录变化。provider 会在 registry 中创建类似如下的目录结构
其中 provider 注册的 url 为,会创建 com.foo.BarService、provider 和 providerUrl 节点
- dubbo / com.test.service.TestDubboService / providers / dubbo % 3A % 2F % 2F192.168.0.102 % 3A20880 % 2Fcom.test.service.TestDubboService % 3Fapplication % 3Dcom.test.demo % 26default.export % 3Dtrue % 26export % 3Dtrue % 26generic % 3Dfalse % 26interface % 3Dcom.test.service.TestDubboService % 26pid % 3D45599 % 26side % 3Dprovider % 26timestamp % 3D1515313385792
接下来会创建并订阅 configurators 节点,订阅的意思就是监听 configurators 及其子节点,创建 configurators 的时候会添加 listener,provider 端监听 configurators 的 listener 是:
- com.alibaba.dubbo.registry.integration.RegistryProtocol.OverrideListener#notify
在治理中心中修改 provider 的配置的时候,注册中心会通知监听的 listener,provider 会进行相关配置。
export 服务是 dubbo 关键路径中的第一步,此时 dubbo 已经具备了被 consumer 自动发现并调用的条件,接下来就是 consumer 发现服务。
来源: https://www.cnblogs.com/sunshine-2015/p/8228483.html