服务导出的入口方法为ServiceBean.export(),此方法会调用ServiceConfig.export()方法,进行真正的服务导出。
服务概念的演化:
- DemoService接口表示一个服务,此时的服务表示服务定义
- DemoServiceImpl表示DemoService服务的具体实现,此时的服务表示服务的具体实现
- DemoService+group+version表示一个服务,此时的服务增加了分组和版本概念
- http://192.168.1.112:80/com.huanglei.DemoService表示一个服务,此时的服务增加了机器IP和Port,表示远程机器可以访问这个URL来使用com.huanglei.DemoService这个服务
- http://192.168.1.112:80/com.huanglei.DemoService?timeout=3000&version=1.0.1&application=dubbo-demo-provider-application表示一个服务,此时的服务是拥有参数的,比如超时时间、版本号、所属应用
在dubbo中就是用的最后一种方式来表示服务的。
服务导出要做的几件事情:
- 确定服务的参数
- 确定服务支持的协议
- 构造服务最终的URL
- 将服务URL注册到注册中心去
- 根据服务支持的不同协议,启动不同的Server,用来接收和处理请求
- 因为Dubbo支持动态配置服务参数,所以服务导出时还需要绑定一个监听器Listener来监听服务的参数是否有修改,如果发现有修改,则需要重新进行导出
确定服务的参数
在执行ServiceConfig.export()时,此时ServiceConfig对象就是一个服务,我们已经知道了这个服务的名字(就是接口的名字),并且此时这个服务可能已经有一些参数了,就是@Service注解上所定义的参数。
但是在Dubbo中,除开可以在@Service注解中给服务配置参数,还有很多地方也可以给服务配置参数,比如:
- dubbo.properties文件,你可以建立这个文件,dubbo会去读取这个文件的内容作为服务的参数,Dubob的源码中叫做PropertiesConfiguration
- 配置中心,dubbo在2.7版本后就支持了分布式配置中心,你可以在Dubbo-Admin中去操作配置中心,分布式配置中心就相当于一个远程的dubbo.properties文件,你可以在Dubbo-Admin中去修改这个dubbo.properties文件,当然配置中心支持按应用进行配置,也可以按全局进行配置两种,在Dubbo的源码中AppExternalConfiguration表示应用配置,ExternalConfiguration表示全局配置。
- 系统环境变量,你可以在启动应用程序时,通过-D的方式来指定参数,在Dubbo的源码中叫SystemConfiguration
- 再加上通过@Service注解所配置的参数,在Dubbo的源码中叫AbstractConfig
服务的参数可以从这四个位置来,这四个位置上如果配了同一个参数的话,优先级从高到低如下:
SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
可以看出,-D方式配置的参数优先级最高,配置中心次之,注解随后,dubbo.properties最后。
你可以在dubbo.properties文件或配置中心中通过一下形式去给一个服务配置参数:
dubbo.service.{interface-name}[.{method-name}].timeout=3000
-D方式也类似。
从以上分析我们可以看出,在服务导出时,首先得确定服务的参数。
当然,服务的参数除开来自于服务的自身配置外,还可以来自其上级。
比如如果服务本身没有配置timeout参数,但是如果服务所属的应用的配置了timeout,那么这个应用下的服务都会继承这个timeout配置。
所以在确定服务参数时,需要先从上级获取参数,获取之后,如果服务本身配置了相同的参数,那么则进行覆盖。
确定服务支持的协议
确定服务所支持的协议还是比较简单的,就是看用户配了多少个Protocol。和服务参数意义,Protocol也是可以在各个配置点进行配置的。
- 首先在SpringBoot的application.properties文件中就可能配置了协议
- 也可能在dubbo.properties文件中配置了协议
- 也可能在配置中心中也配置了协议
- 也可能通过-D的方式也配置了协议
所以在服务导出时,需要从以上几个地方获取协议,结果可能是一个协议,也可能是多个协议,从而确定出协议。
构造服务最终的URL
有了确定的协议