Dubbo——服务暴露过程分析
这篇文章来叙述对dubbo的服务暴露前的准备工作:
使用Spring配置文件,通过main方法来启动spring容器,来观察dubbo服务的启动过程。
dubbo配置文件
<context:component-scan base-package="com.wk.order.service.impl,com.wk.order.facade.impl"/><dubbo:application name="dubbo-order-service"/><!--<dubbo:registry address="multicast://224.5.6.7:1234" />--><dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" /><dubbo:protocol name="dubbo" port="20880"/><dubbo:service interface="com.wk.common.facade.OrderFacade" ref="orderFacadeImpl" loadbalance="roundrobin"/>
在说明暴露服务的流程之前,先明确知道几个对象,在dubbo里,默认使用JavassisFactory动态代理工厂来动态的产生扩展对象,然后根据扩展对象的export方法,根据url的参数配置,例如上述为dubbo协议,注册中心为zookeeper。这样呢就会根据url的配置使用DubboProtocol来进行服务的暴露,创建NettyServer。默认为netty启动。默认也是Dubbo。会使用ZookeeperRegistry把服务注册的注册中心。
在Spring容器启动时,会对Bean进行加载,Dubbo通过Spring自定义标签扩展了自己的标签。把属于Dubbo的实体Bean注册到Spring里。
public void init() {registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));}
上面注册了ServiceBean这个类,那么ServiceBean是什么什么东西呢,观察ServiceBean对象,它实现了InitializingBean接口,在该接口中有一个afterPropertiesSet方法,在Bean的属性初始化时,Spring会默认调用该方法。该方法里调用了关于dubbo的开始 export方法。那么dubbo的服务暴露export方法就在这里开始起航了。
第一步:在afterPropertiesSet里会从applicationContext里获取诸多实例,诸多实例就是上述注册器里的Bean.class。经过这一层之后,就会调用export方法。此时在ServiceConfig对象里,已经有了关于dubbo配置的一些内容。
走入export方法后共有多个方法一连串的调用:
doExport方法对一些配置进行检测和获取,检查provider,application,module,registries,monitor这些参数是否为空,是否是GenericService类型的服务,检查要注册的bean的引用和方法等。虽然不知道这些是做什么用的。
doExportUrls:很明显,它这是获取注册中心的url路径。因为dubbo支持多注册中心,所以需要获取多个注册中心的url。
registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=dubbo-order-service&dubbo=2.5.7&pid=9720®istry=zookeeper×tamp=1535884939183
doExportUrlsFor1Protocol:该方法是真正的开始暴露服务了,在这个方法里有一大堆的参数在往map里塞。这就是在为服务暴露做准备。dubbo的主线是Invoker对象,而url就是包含各种配置在内的一个协议字符串。根据这个字符串能够做好多的事情。
doExportUrlsFor1Protocol方法很长,其中有几处需要关注:
1、获取主机地址,这段逻辑曾经在线上部署时,出现过问题。如今恍然大悟。在获取主机地址的逻辑中:优先从配置里获取主机地址,否则从本地的InetAddress获取地址,再者从Socket里获取地址。
2、本地服务不需要notify。即injvm是不需要进行notiry的。injvm是本地暴露的协议。类似:registry等协议。
if ("injvm".equals(protocolConfig.getName())) {protocolConfig.setRegister(false);map.put("notify", "false");}// 导出服务String contextPath = protocolConfig.getContextpath();if ((contextPath == null || contextPath.length() == 0) && provider != null) {contextPath = provider.getContextpath();}String host = this.findConfigedHosts(protocolConfig, registryURLs, map);Integer port = this.findConfigedPorts(protocolConfig, name, map);
在一大堆参数配置完毕后,根据scope的配置决定是否要进行本地暴露。
本地暴露过程:本地暴露过程相对简单,主要是通过扩展机制使用JavassitFactory对业务类进行动态代理生成一个动态代理对象,使用injvmProtocol把invoker包装为一个Exporter。最后放到ServiceConfig的一个属性exports里。exports是一个list集合。
对于本地暴露的过程,为什么要这样进行暴露,以及包装过程中都做了什么,有什么值得去包装的呢?
根据我的理解,在这里其实是一个IOC和AOP的体现,从Dubbo的扩展机制,实现了一个SPI自定义扩展,你可以加上无数个扩展。再加上Adaptive增强注解+装饰机制达到了AOP的效果。对于这里的包装有什么效果呢,目前知道和过滤器链有关。先打上个标记。
对于远程暴露,和本地暴露也是同样的过程,只不过Dubbo在把Invoker包装为Exporter的过程中,做了两件事情:
1、创建序列化和反序列化实例,根据扩展机制生成Server实例,默认使用NettyServer,还给Server添加了经过一系列包装的handler对象,因为对网络编程编码,解码,Netty拆包,粘包,dubbo的线程池处理不了解,只能先到这里了。总之创建Server实例完成之后,就返回了Exporter对象。
2、在返回Exporter对象之后,RegisterProtocol继续发挥它的余热,但是却也做了一个了不起的事情。接下来它需要把服务通过扩展机制得到的注册中中心,把服务注册到注册中心上。
在返回Export对象之后,register第一个要做的事情就是打通注册中心,本例为zookeeper,在看源码过程中,这里会在zk上先建立一个/dubbo的节点,并生成一个监听。然后返回回来后,依据提供者的配置,获取url参数。接下来的事情就比较简单了,根据zkClient直接在dubbo上创建节点就OK了。
还会调用registry的subscribe方法,这里主要是加了注册订阅Listener,在创建出其他节点之后会调用notify方法。notify方法会做两件事,1. 会将url改动更新到缓存的配置文件中。2. 会通知listener变动,此通知为全量通知
下面来看一下我的zookeeper的节点内容,从第一行看起,会看到在 /dubbo/com.wk.common.facade.OrderFacade下一共有4个节点,分别是 consumers,configurators,routers,providers。其中在providers下的内容见第一个红框,根据显示,可以看到providers下有一大堆的内容,想来这就是我们在dubbo上注册的那个url喽。
对于configurators和routers都是为空,相比应该是在dubbo控制台上做一些处理,之后就会有内容了。也就是说,当这些节点有变化的时候,就会通知ZookeeperRegister发生变化。
从官方的说明来说,服务启动的时候,会向providers目录下写入自己的url地址。估计我这里的consumbers是以前消费者启动写入的。
暂时先这样,有不同见解的,欢迎评论。
Dubbo——服务暴露过程分析相关推荐
- 面试官问我:解释一下Dubbo服务暴露
今天我们要分析的就是Dubbo的服务暴露过程,这个过程属于Dubbo的核心过程之一了,因为Dubbo的大体流程就是服务暴露->服务引用->服务消费这几个主流程,当然还会涉及到注册发现.负载 ...
- Dubbo服务暴露的流程
在Dubbo服务暴露中,需要被暴露的服务的接口类首先会通过proxyFactory代理工厂获得代理的对象invoker,而暴露之后的服务被调用,也将都会通过这个invoker来调用相关的类. 在dub ...
- Dubbo服务暴露原理
服务暴露原理 配置文件 IOC容器启动,加载配置文件的时候 Dubbo标签处理器,解析每一个标签 封装成对应的组件 service 解析service标签 将service标签信息,封装成Servic ...
- Dubbo服务暴露(导出)流程
Dubbo作为一个Rpc框架,服务端必须得将自己暴露出去,以便客户端的调用,所以我们来看一下dubbo是如何将服务进行暴露的. 首先我们知道,启动dubbo得进行一些配置,如下图所示的一些dubbo标 ...
- dubbo服务暴露流程总结
这篇文章主要总结一下dubbo服务端启动的时候服务暴露过程,虽然官方网站和各种博客上已经有很多介绍服务暴露的帖子,但还是想把自己跟源码过程中遇到的问题和心得记录下来,算是个总结,并且本篇文章是基于du ...
- dubbo服务暴露原理解析
配置解析 dubbo 的各个配置项,详细的可以参考官网 只有 group,interface,version 是服务的匹配条件,三者决定是不是同一个服务,其它配置项均为调优和治理参数 所有的配置最终都 ...
- 阿里面试官:你知道Dubbo的服务暴露机制么?
点赞再看,养成习惯,微信搜一搜[三太子敖丙]关注这个喜欢写情怀的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系 ...
- Dubbo/Dubbox的服务暴露(一)
前言 源码入手 平时我要了解一个框架,基本会去从他的Listener入手,如果web.xml中没有配置listener可能还会有 filter,这是spring给我们的启示,可是当要去了解dubbo的 ...
- php dubbo 接口测试工具,dubbo服务自动化测试搭建
java实现dubbo的消费者服务编写:ruby实现消费者服务的接口测试:通过消费者间接测试dubbo服务接口的逻辑 内容包括:dubbo服务本地调用环境搭建,dubbo服务启动,消费者部署,脚本编写 ...
最新文章
- 跑python gpu利用率低_训练效率低?GPU利用率上不去?快来看看别人家的tricks吧~...
- Spring State Machine:它是什么,您需要它吗?
- Centos7使用Docker创建Oracle11g
- 分享一个在线vim网站
- C++基础知识总结----类的进阶知识点
- 【图神经网络入门】GAT图注意力网络
- 严加监管是否能解决超载问题
- Gradle教程--基础篇
- red5搭建流媒体直播系统
- 生物信息学基础知识Day4
- 清空回收站如何找回?
- NRZ、RZ信号的时频域区别及它们的谱效率
- 智能手表,不再只是手机品牌的“附属品”
- c语言课程设计雪花飞舞,雪花飞舞--c语言课程设计.doc
- ai人工智能课程百度云_云AI就像核电
- matlab弹道仿真,战役战术导弹弹道仿真在simulink下如何实现
- 两图像间的单应性矩阵估计
- 大众mpv_大众mpv商务车7座车型 大众mpv都有哪些?
- 宽带语谱图(wideband spectrogram)和窄带语谱图(narrowband spectrogram)的区别
- 实战4 - 汽车行驶工况构建
热门文章
- 苹果自带的清理软件_软件| 卸载软件、清理文件,你只需Revo Uninstaller Pro(自带注册程序)...
- Arduino基础与常用函数
- Java中的异常分类[乐乐独记]
- 爬虫:Iron WebScraper 2022 for NET
- 等比缩放公式_等比缩放算法
- python设置默认utf8编码_Python设置默认编码为utf8的方法
- [编译原理课设] 自动机的状态转换图表示
- 华硕服务器不分区重装系统,华硕笔记本重装系统不能进入系统怎么办
- oracle 实用记录
- DHTMLX JS Gantt Library 7.1.13