RPC简化类图
RPC模块核心接口和抽象实现
默认实现Dubbo协议的接口和抽象实现
服务发布过程
调用过程
上图是服务提供者暴露服务的主过程:
首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl),然后通过ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到Invoker的转化。接下来就是Invoker转换到Exporter的过程。
Dubbo处理服务暴露的关键就在Invoker转换到Exporter的过程(如上图中的红色部分),Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由Dubbo自己实现。
案例介绍
从上面知道,利用Spring的解析收集到dubbo:service、dubbo:registry等标签的配置,然后将这些配置都存至ServiceConfig,RegistryConfig中,然后调用ServiceConfig的export()方法来进行服务的发布与注册
先看一个简单的服务端例子,dubbo配置如下:
<dubbo:application name="helloService-app" />
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />
<dubbo:service interface="com.demo.dubbo.service.HelloService" ref="helloService" />
<bean id="helloService" class="com.demo.dubbo.server.serviceimpl.HelloServiceImpl"/>
- 有一个服务接口HelloService,以及它对应的实现类HelloServiceImpl
- 将HelloService标记为dubbo服务,使用HelloServiceImpl对象来提供具体的服务
- 使用zooKeeper作为注册中心
服务发布过程
一个服务可以有多个注册中心,多个服务协议
多注册中心信息(注册的是整个application):
首先根据注册中心配置,即上述的ZooKeeper配置信息聚合在一个URL对象中,内容如下:
registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=helloService-app&localhost=true®istry=zookeeper
多协议信息(提供具体服务):
由于上述我们没有配置任何协议信息,就会使用默认的dubbo协议,开放在20880端口,也就是在该端口,对外提供上述的HelloService服务,注册的协议信息也转化成一个URL对象,如下:
dubbo://127.0.0.1:20880/com.demo.dubbo.service.HelloService?anyhost=true&application=helloService-app&dubbo=2.0.13&interface=com.demo.dubbo.service.HelloService&methods=hello&prompt=dubbo&revision=
把注册中心信息和协议信息组合起来,依次来进行服务的发布,整个过程的伪代码如下:
//获取注册中心信息
List<URL> registryURLs = loadRegistries();
for (ProtocolConfig protocolConfig : protocols) {
//根据每一个协议配置构建一个URL
URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
for (URL registryURL : registryURLs) {
String providerURL = url.toFullString();
//将协议信息添加到注册中心信息后面
Invoker<?> invoker = proxyFactory.getInvoker(ref