下图是Dubbo官网的一个服务提供者暴露服务的主过程:上图是服务提供者暴露服务的主过程:app
首先 ServiceConfig
类拿到对外提供服务的实际类 ref(如:HelloWorldImpl),而后经过 ProxyFactory
类的 getInvoker
方法使用 ref 生成一个 AbstractProxyInvoker
实例,到这一步就完成具体服务到 Invoker
的转化。接下来就是 Invoker
转换到 Exporter
的过程。socket
Dubbo 处理服务暴露的关键就在 Invoker
转换到 Exporter
的过程,上图中的红色部分。下面咱们以 Dubbo 和 RMI 这两种典型协议的实现来进行说明:ide
Dubbo 协议的 Invoker
转为 Exporter
发生在 DubboProtocol
类的 export
方法,它主要是打开 socket 侦听服务,并接收客户端发来的各类请求,通信细节由 Dubbo 本身实现。ui
RMI 协议的 Invoker
转为 Exporter
发生在 RmiProtocol
类的 export
方法,它经过 Spring 或 Dubbo 或 JDK 来实现 RMI 服务,通信细节这一块由 JDK 底层来实现,这就省了很多工做量。url
在ServiceConfig.export()或ReferenceConfig.get()初始化时,将Bean对象转换暴露服务或请求服务的URL,全部Bean属性转成URL的参数。spa
而后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不一样协议的服务暴露或引用。code
url参数列只有group,interface,version是服务的匹配条件,三者决定是否是同一个服务,其它配置项均为调优和治理参数对象
有注册中心配置:<dubbo:registry address="zookeeper://10.20.153.10:2181" />get
ServiceConfig解析出的URL的格式为:io
registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")
1)基于扩展点的Adaptive机制,经过URL的"registry://"协议头识别,就会调用RegistryProtocol的export()方法,将export参数中的提供者URL,先注册到注册中心,再从新传给Protocol扩展点进行暴露:
dubbo://service-host/com.foo.FooService?version=1.0.0
2)基于扩展点的Adaptive机制,经过提供者URL的"dubbo://"协议头识别,就会调用DubboProtocol的export()方法,打开服务端口。
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
Exporter<?> exporter = protocol.export(invoker);
具体服务àInvoker àExporter Exporter是负载打开服务端口等待请求。
注册中心配置:<dubbo:registry address="zookeeper://10.20.153.10:2181" />
ReferenceConfig解析出的URL的格式为:
registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")
基于扩展点的Adaptive机制,经过URL的"registry://"协议头识别,就会调用RegistryProtocol的refer()方法,基于refer参数中的条件,查询提供者URL,如:
dubbo://service-host/com.foo.FooService?version=1.0.0
基于扩展点的Adaptive机制,经过提供者URL的"dubbo://"协议头识别,就会调用DubboProtocol的refer()方法,获得提供者引用。
而后RegistryProtocol将多个提供者引用,经过Cluster扩展点,假装成单个提供者引用返回。
invoker = refprotocol.refer(interfaceClass, urls.get(0));
(T) proxyFactory.getProxy(invoker);
基于ProtocolFilterWrapper类,将全部Filter组装成链,在链的最后一节调用真实的引用。
基于ProtocolListenerWrapper类,将全部InvokerListener和ExporterListener组装集合,在暴露和引用先后,进行回调。
包括监控在内,全部附加功能,所有经过Filter拦截实现。