Dubbo服务引用

大致流程

Provider将服务暴露出来并且注册到注册中心,而Consumer通过注册中心获取Provider的信息,之后将自己封装成一个调用类去与Provider进行交互。

首先需要将所有调用转化为Dubbo中我们熟悉的Invoker,再通过代理类去远程获取服务。

大致流程如下:


服务引用策略

服务的引用和服务的暴露原理相似,都是Spring自定义标签机制解析生成对应的Bean,在之前服务暴露使用到的Provider Service使用的是ServiceBean,而Comsumer Reference使用的ReferenceBean

服务暴露是在SpringIOC容器完成刷新后开始暴露的,而服务的引入则分为两种,分别是饿汉式懒汉式

饿汉式是通过实现Spring的InitializingBean接口中的afterPropertiesSet()实现的,通过上图中ReferenceBean的实现也可以获知,而容器通过调用ReferenceBean中的afterPropertiesSet()时引入服务。

懒汉式是只有某个服务被注入到其他类时才开始启动引入流程。

默认情况下,Dubbo会使用懒汉式引入策略,如果需要使用饿汉式,需要在<dubbo:reference/>中配置init开启。

并且通过上图我们还可以看到ReferenceBean还实现了FactoryBean,Dubbo通过这个实现来进行懒汉式引用服务。


服务引用的三种方式

服务引用分为三种方式:

  • 本地引入
  • 直接使用连接引入远程服务
  • 通过注册中心引入远程服务

本地引入的基础是之前介绍过的本地暴露,某个服务端可能同时是Provider又是Comsumer,并且可能会自己调用本地的服务,这种情况下不需要进行网络调用,所以引入了本地引用,来避免不必要的网络开销。

服务引入时,第一步做的就是在本地中查找是否有可用的本地服务。

直连引入服务,这种方式不需要注册中心的支持,绕过了注册中心,直接通过Url来引用远程服务,具体实现是在Comsumer中写死Provider的具体地址,然后在调用时直接连接即可,一般用于测试,如果大量服务之间都使用直连引入,那么服务集群之间的关系将错综复杂,变得那以维护和管理。

注册中心引入服务,Comsumer通过注册中心获取Provider的相关信息,然后进行服务的引入,其中还涉及到多注册中心,服务集群时的负载均衡,以及容错机制。


服务引入流程解析

前提:服务引入选择默认的懒汉式引入策略并且使用注册中心引入服务。

服务引入的入口是ReferenceBean.getObject()

然后会调用父类ReferenceConfig.get()

进入init()方法,前面的一大串代码就是做if else判断的配置检查并且将配置放入map,构建完毕后的map如下:

再进入createProxy()方法

如果是本地引入的话,会构建一个本地引入的URL然后进行服务的引入,即图示中的refprotocol.refer()

不是本地引入,那么就是远程引入了,接下来需要判断的是点对点直连provider还是通过注册中心拿到provider信息再进行连接。

以下是点对点直连:

以下是通过注册中心连接:

最终拼接出来的URL如下图所示:

方法最后通过代理封装invoker返回代理实现。

上图就是整个服务引用流程。

但是还有很多细节,比如如何从注册中心获得Provider,invoker内部结构是怎么样的

在上面URL的截图中,我们可以看到此时的协议是registry,因此会调用RegistryPotocol.refer()

获取注册中心实例,之后调用doRefer()

RegistryDirectory类是实现了NotifyListener接口的,注册中心的监听功能就此而来。

public class RegistryDirectory<T> extends AbstractDirectory<T> implements NotifyListener {}public interface NotifyListener {void notify(List<URL> var1);
}

向注册中心注册自身信息之后,会向注册中心订阅providersconfiguratorsrouters节点信息。订阅之后RegistryDirectory会收到这几个节点的信息,并触发DubboInvoker的生成,即用于远程调用的invoker。

再通过cluster封装得到invoker,因此一个服务可能有多个提供者,最终在ProviderConsumerRegTable记录这些信息,然后返回invoker。

拿到Provider的信息之后就会通过监听触发DubboProtocol.refer()

重点在getClients()方法中,这个方法是用于获取客户端实例的,实例类型为ExchangeClient[],底层依赖Netty进行通讯,并且是默认共享连接的。

再进入initClient()方法中看看初始化客户端的具体细节:

最后返回的(ExchangeClient) client封装的是NettyClient

最后得到的Invoker如下,其中记录到了许多信息:

最后调用return proxyFactory.getProxy(this.invoker);将代理对象返回。

以下是整个服务引用的流程图:


总结

首先是通过配置构建URL,再通过协议头自适应拓展得到具体的实现类进行服务引入,之后消费者向注册中心注册自己的信息,然后订阅相关信息,得到远程服务提供者的信息,最后通过NettyClient进行连接通讯。

还会通过DirectoryCluster进行多个服务提供者的合并、屏蔽、容错以及负载均衡,最终将封装好的可执行体Invoker通过动态代理封装得到代理对象返回。

以上。

整理不易,如果对你有用的话留个三连吧!

Dubbo服务引用过程相关推荐

  1. 理解 Dubbo 服务引用

    为什么80%的码农都做不了架构师?>>>    dubbo 服务引用过程 dubbo 的使用过程中消费者端会依赖服务端提供的 api 包(接口 jar 包) , 这些 api 包中只 ...

  2. Dubbo服务调用过程流程图

    Dubbo服务调用过程主要有两个阶段 1.服务消费方发起调用请求,并处理结果 2.服务提供方接收请求,并返回处理结果 第一阶段 消费者客户端发起rpc请求 这个阶段会将请求数据发送到服务提供者,并且在 ...

  3. 面试杀手锏之Dubbo服务调用过程

    点赞再看,养成习惯,微信搜一搜[三太子敖丙]关注这个喜欢写情怀的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系 ...

  4. Dubbo服务引用原理

    服务引用原理 配置文件 通过Spring容器加载 每一个标签,对应一个解析类 Reference 对应ReferenceBean 实现了FactoryBean FactoryBean 工厂Bean 引 ...

  5. 初步了解学习将传统单机应用改造成Dubbo服务的过程

    Dubbo作为RPC框架,实现的效果就是调用远程的方法就像在本地调用一样.如何做到呢?就是本地有对远程方法的描述,包括方法名.参数.返回值,在Dubbo中是远程和本地使用同样的接口:然后呢,要有对网络 ...

  6. Dubbo 源码分析 - 服务引用

    1. 简介 在上一篇文章中,我详细的分析了服务导出的原理.本篇文章我们趁热打铁,继续分析服务引用的原理.在 Dubbo 中,我们可以通过两种方式引用远程服务.第一种是使用服务直联的方式引用服务,第二种 ...

  7. dubbo(4) Dubbo源码解析之服务引入过程

    来源:https://juejin.im/post/5ca37314e51d454cb97d9c40 1. 简介 在 Dubbo 中,我们可以通过两种方式引用远程服务.第一种是使用服务直连的方式引用服 ...

  8. dubbo(5) Dubbo源码解析之服务调用过程

    来源:https://juejin.im/post/5ca4a1286fb9a05e731fc042 Dubbo源码解析之服务调用过程 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与 ...

  9. Dubbo 服务本地缓存

    开篇 根据官方图,dubbo调用者需要通过注册中心(例如:ZK)注册信息,获取提供者,但是如果频繁往ZK获取信息,肯定会存在单点故障问题,所以dubbo提供了将提供者信息缓存在本地的方法. Dubbo ...

最新文章

  1. MPB:扬州大学王梦芝组-​​反刍动物瘤胃原虫的分离培养与形态学分析
  2. 解决Mysql错误Too many connections的方法
  3. MySQL用source命令导入不记入binlog中【原创】
  4. 红帽linux6.0安装教程,第 14 章 引导安装程序
  5. JavaFX即将推出您附近的Android或iOS设备吗?
  6. c语言中状态机的作用,C语言中的状态机
  7. web.xml的contextConfigLocation作用及自动加载applicationContext.xml
  8. idea离线安装lombock插件
  9. linux dhcpv6有状态配置,Centos 7下IPV6 有状态DHCPV6配置
  10. java实现电子面单pdf生成_电子面单打印功能实现方法
  11. Macbook pro (m1)突然没有办法按住shift打出大写R
  12. HardLink SymbolLink Junctions
  13. 南师大GIS考研数据库2015年第三题
  14. 还不清楚如何编辑图片上的文字的话,就看看这篇文章吧
  15. 初学入门YOLOv5手势识别之制作并训练自己的数据集
  16. 基于ArrayList实现HashMap代码
  17. 复选框的全选反选实现(即购物车的复选框实现)
  18. mp3怎么转换成mp4?
  19. 语法转换_【语法专题】句型转换(上)
  20. Sublime text 3 汉化 POJIE版 分享

热门文章

  1. 105. Leetcode 121. 买卖股票的最佳时机 (动态规划-股票交易)
  2. tkinter 笔记:列表部件 listbox (莫烦python 笔记)
  3. pytorch学习:xavier分布和kaiming分布
  4. 文巾解题 797. 所有可能的路径
  5. 数据结构与算法基础知识集锦
  6. mapreduce编程实例(3)-求平均值
  7. c语言数字的拆解_C语言解决变态推理题
  8. python 拓扑排序 dfs bfs_拓扑排序的DFS和BFS
  9. 【图像处理opencv】_图像锐化
  10. 【Python刷题】_2