java开发分布式服务框架Dubbo服务引用过程详解

 更新时间:2021年11月15日 15:22:16   作者:又蠢又笨的懒羊羊程序猿  
这篇文章主要为大家介绍了java开发分布式服务框架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通过动态代理封装得到代理对象返回。

以上就是java开发分布式服务框架Dubbo服务引用详解的详细内容,更多关于Dubbo服务引用的资料请关注脚本之家其它相关文章!

相关文章

  • 解析Spring中的静态代理和动态代理

    解析Spring中的静态代理和动态代理

    学习 Spring 的过程中,不可避免要掌握代理模式。这篇文章总结一下代理模式。顾名思义,代理,就是你委托别人帮你办事,所以代理模式也有人称作委托模式的。比如领导要做什么事,可以委托他的秘书去帮忙做,这时就可以把秘书看做领导的代理
    2021-06-06
  • Spring Boot利用JSR303实现参数验证的方法实例

    Spring Boot利用JSR303实现参数验证的方法实例

    这篇文章主要给大家介绍了关于Spring Boot利用JSR303实现参数验证的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-05-05
  • idea快速搭建springboot项目的操作方法

    idea快速搭建springboot项目的操作方法

    下面小编就为大家分享一篇idea快速搭建springboot项目的操作方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • Spring Boot+RabbitMQ 通过fanout模式实现消息接收功能(支持消费者多实例部署)

    Spring Boot+RabbitMQ 通过fanout模式实现消息接收功能(支持消费者多实例部署)

    这篇文章主要介绍了Spring Boot+RabbitMQ 通过fanout模式实现消息接收(支持消费者多实例部署),本文通过案例场景分析给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • JavaWeb.servlet的基本使用方法详解

    JavaWeb.servlet的基本使用方法详解

    Servlet指在服务器端执行的一段Java代码,可以接收用户的请求和返回给用户响应结果,下面这篇文章主要给大家介绍了关于JavaWeb.servlet基本使用的相关资料,需要的朋友可以参考下
    2022-04-04
  • 解析spring加载bean流程的方法

    解析spring加载bean流程的方法

    这篇文章主要介绍了解析spring加载bean流程的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • Spring之InitializingBean接口和DisposableBean接口的使用

    Spring之InitializingBean接口和DisposableBean接口的使用

    这篇文章主要介绍了Spring之InitializingBean接口和DisposableBean接口的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • SpringBoot各种注解详解

    SpringBoot各种注解详解

    SpringBoot的一个核心功能是IOC,就是将Bean初始化加载到容器中,Bean是如何加载到容器的,可以使用SpringBoot注解方式或者Spring XML配置方式。SpringBoot注解方式减少了配置文件内容,更加便于管理,并且使用注解可以大大提高了开发效率
    2022-12-12
  • Springboot集成SSE实现单工通信消息推送流程详解

    Springboot集成SSE实现单工通信消息推送流程详解

    SSE简单的来说就是服务器主动向前端推送数据的一种技术,它是单向的,也就是说前端是不能向服务器发送数据的。SSE适用于消息推送,监控等只需要服务器推送数据的场景中,下面是使用Spring Boot来实现一个简单的模拟向前端推动进度数据,前端页面接受后展示进度条
    2022-11-11
  • PowerJob的IdGenerateService工作流程源码解读

    PowerJob的IdGenerateService工作流程源码解读

    这篇文章主要为大家介绍了PowerJob的IdGenerateService工作流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01

最新评论