Dubbo服务暴露
服务暴露分为什么?
- 本地服务暴露;
- 远程服务暴露
本地服务暴露和远程服务暴露概念
本地服务暴露:指将服务暴露到JVM中,不用通过注册中心或协议进行网络通信。
远程服务暴露:指暴露到远程IP和端口,进行网络通信。
为什么需要本地服务暴露?
因为在Dubbo中一个服务有可能本身即是生产者,也是消费者,可能出现自己调用自己的情况。此时没有必要进行网络通信。
服务暴露流程
在启动过程中,在Spring容器启动时,会对Bean进行加载,Dubbo通过Spring自定义标签扩展了自己的标签。DubboNamespaceHandler
在DubboNamespaceHandler中进行初始化,在ServiceBean中进行服务的暴露。ServiceBean实现了Spring的ApplicationListener,ApplicationListener提供了方法在bean初始化后需要处理的一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。在 onApplicationEvent()方法中可以看到export()
服务暴露方法。
一直进入到ServiceConfig 中的doExportUrls()方法
首先获取配置的注册地址。然后根据不同的协议进行服务暴露(一个应用可以有多种协议)。
进入 doExportUrlFor1Protocol()
方法中,
首先设置默认协议"dubbo",获取注册中心的地址(是否配置》直接获取》通过Sokcet获取),获取端口,填充一些参数……等等,最后进行服务暴露。
本地服务暴露
主要通过扩展机制使用JavassistProxyFactory对提供的服务类进行动态代理生成一个动态代理对象,然后使用InjvmProtocol将invoker对象包装为一个Exporter。
本地服务暴露出的url格式:injvm://127.0.0.1/{接口全路径}…
本地服务暴露使用的是injvm协议,injvm协议是一个伪协议,不开启端口,不能被远程调用,只能在JVM内直接关联。
远程服务暴露
和本地暴露类似,但是Dubbo在将Invoker对象包装为Exporter的过程中,做了两件事:
- 创建序列化和反序列实例,根据扩展机制生成Server实例,默认使用NetterServer。
- 在返回Exporter对象之后,RegisterProtocol把服务注册到注册中心上。首先会在zk上建立一个dubbo节点,并生成一个监听。当url改动后,会通知 listener 变动。
远程服务暴露出的url格式:{协议}://{ip}:{prot}/{接口全路径}...
服务暴露本质
就是暴露出url地址,打开netty服务器,监听端口(默认端口20880)。
服务发布整个过程:
- 暴露本地服务
- 暴露远程服务
- 启动netty
- 连接zk
- 向zk注册
- 监听zk