dubbo原理(dubbo原理和机制 面试)

本篇文章给大家谈谈dubbo原理,以及dubbo原理和机制 面试对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Dubbo的通讯方式:NIO+长连接

Dubbo默认使用长连接。

Dubbo序列化默认使用的是修改过的Hessian协议,这是一种高效的二进制协议。Hessian协议与具体语言无关。

Dubbo服务端与消费端使用的是Mina NIO框架。

Java NIO

NIO,即非阻塞式IO,Java NIO的工作原理如下:

1,由一个专门的线程来正雀处理所有的IO事件,并负责分发。

2,数清孙事件驱动机制:事件到的时候触发,而不是同步的去监视事件。

3,线程通讯:线程之间通过wait,notify等方式通信,保证每次上下文切换都是有意义的,减少无效的切换。

NIO的事件驱动机薯链制是如何实现的?

[img]

dubbo泛化调用使用及原理解析

通常我们想调用别人的dubbo服务时,我们需要在项目中引入对应的jar包。而泛化调用的作用是,我们无需依赖相关jar包,也能调用到该服务。

这个特性一般使用在网关类项目中,在业务开发中基本不会使用。

假设我现在要调用下面的接口服务

在xml文件做以下配置

然后注入使用

在两种调用方式中,我们都需要使用被调用接口的字符串参数生成GenericService,通过GenericService的$invoke间接调用目标接口的接口。

$invoke的三个参数分别为,方法名,方法参数类型数组,方法参数数组。

可以看到泛化调厅并用的一个复杂性弊伏唤在于$invoke的第三个参数的组装,下面介绍几种复杂入参的调用方式

首先丰富提供者接口

与入参相似,虽然$invoke的返回定义为Object,实际上针对不同类型有不同的返回。

泛化调用和直接调用在消费者者端,在 使用上的区别 是,我们调用服务时使用的接口为GenericService,方法为$invoker。在 底层的区别 是,消费者端发出的rpc报文发生了变化。

在使用上,不管哪种配置方式,我们都需要配置generic=true

设置generic=true后,RefereceConfig的interfaceClass会被强制设置为GenericService

这也使得我们的RefereanceBean返回的是GenericService类型的代理。

生成的代理是GenericService的代理只是我们使用方式上的变化,更为核心的是,底层发送的rpc报文发生了什么变化。

Dubbo的rpc报文分为header和body两部分。我们这边只需要关注body部分。构造逻辑如下

那么我们通过直接调用与泛化调用ByeService的bye方法在报文上有啥区别呢?

我一开始以为报文中的path是GenericeService,其实并没有,path就是我们调用的目标方法。

path来源???todo

而报文中的方法名,方法参数类型以及具体参数,还是按照GenericeService的$invoke方法入参传递的。

这么个二合一的报文,发送到提供者那边,它估计也会很懵逼,我应该怎么执行?

所以针对泛化调用报文还会把generic=true放在attchment中传递过去

具体逻辑在GenericImplFilter中。

GenericImplFilter中有很多其他逻辑,比如泛化调用使用的序列化协议,正常接口走泛化调用的模式,我们只需要设置attachment的那部分。

知道消费者端报文发生了什么变化,那么接下来就去看提供者端如何处理这个改造后的报文。

总结一下ReferenceConfig中interfaceClass和interfaceName的区别?(这道面试题好像不错)

interfaceClass用于指定生成代理的接口

interfaceName用于指定发送rpc报文中的path(告诉服务端我要调用那个服务)

消费者泛化调用的rpc报文传递到提供者还不能直接使用,虽然path是对的,但是实际的方法名,参数类型,参数要从rpc报文的参数中提取出来。

GenericFilter就是用来做这件事情。

在提供者这边,针对泛化调用的逻辑全部封装到了GenericFilter,解耦的非常好。

注意第4个条件,一开始很疑惑,后来发现rpc报文中的path是目标接口的,这边invoker.getInterface()返回的肯定就是实际接口了

这边有个疑问,为什么这边还要再次反序列化一次,netty不是有decoder么??

嗯,你别忘了,针对一个POJO你传过来是一个Map,从Map转换为POJO需要这边进一步处理。

这边需要注意一下!!针对接口的泛化调用,抛出的异常都会经过GenericException包装一下。

从功能上来看,泛化调用提供了在没有接口依赖情况下进行的解决方案,丰富框架的使用场景。

从设计上来看,泛化调用的功能还是通租凯过扩展的方式实现的,侵入性不强,值得学习借鉴。

说一下Dubbo的工作原理?注册中心挂了可以继续通信吗?

答案是肯定可以的,我将从下面几点进行说明卖搜:

1.dubbo 的调用流程

2.Dubbo整体设计

3.从源码上说明注册中心挂了还是可以继续通信的

Dubbo 调用流程

架构图

流程说明:

1.Provider(提供者)绑定指定端口并启动服务

2.提供者连接注册中心,并发本机IP、端口、应用信息和提供服务信息发送至注册中心存储

3.Consumer(消费者),连接注册中心 ,并发送应用信息、所求服务信息至注册中心

4.注册中心根据 消费 者所求服务信息匹配对应的提供者列表发送至Consumer 应用缓存。

5.Consumer 在发起远程调用时基于缓存的消费者列表择其一发起调用。

6.Provider 状态变更会实时通知注册中心、在由注册中心实时推送至Consumer

这么设计的意义:

Dubbo 整体设计

其协作流程如下:

从源码上说明注册中心挂了还是可以继续通信的

首先要把消费者注册到Zookeeper注册中心

然后使用RegistryDirectory 监听一下几个目录(会自动触发一次去获取这些目录上的当前数据)

当前所引入的服务的动态配置目录:/dubbo/config/dubbo/org.apache.dubbo.demo.DemoService:1.1.1:g1.configurators

比如监控providers 目录:

当有服务提供者注册,zookeeper会自动推动给订阅的消费者,然后转换为invoker存储到缓存中

我们在看调用时的代码:

我们看到 FailoverClusterInvoker 的doInvoke方法

Invoker invoker = select(loadbalance, invocation, copyInvokers, invoked);

此方法根据负载均衡器去缓存中获取一个invoker,

上面的 copyInvokers 就是上面我们缓存进去的 List

invokers = routerChain.route(getConsumerUrl(), invocation);

总结

在我们系统启动时,已经缓存了注册中心上的所有服务,后续的注册中心挂了只会影响到后续则注册,不会影响调用!

Dubbo分布式的RPC,微服务框架,

包括三个关键功能:基于接口的远程调用,容错与负载均衡,服务自动注册与发现。

Dubbo使得调用远程服务就像调用本地java服务一样简单。

参考Dubbo官方文档:包括实现细节,远程调用细节,服务提供者暴露服务。

主要流程。

1、provider向注册中心去注册

2、consumer从注册中心订阅服务,注册中心会通知consumer注册好的服务

3、consumer调用provider

4、consumer和provider都异步的通知监控中心

基于zk作为注册启斗中心:

【提供者】在【启动】时,向注册中心zk 【注册】自己提供的服务。

【消费者】在【启动】时,向注册中心zk 【订阅】自己所需的服务。

所以是可以的,消费者在启动时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用,消费者本地有一个生产者的列表,他会按照列表继续工作,倒是无法从注册中心去同步最新的服中旁历务列表,短期的注册中心挂掉是不要紧的,但一定要尽快修复,挂掉是不要紧的,但前提是你没有增加新的服务,如果你要调用新的服务,则是不能办到的

【dubbo源码】13. 服务消费方之@Reference依赖注入原理

用法 :

当某个主要注册到spring容器携悔中的bean 的属性上有@Reference注解时,并且 注段肆解的injvm = false时(默认),表明该属性会被注入一个远程接口实例,用作rpc远程调用。

@Reference不是派生自spring默认支持的@Resource和@Autowired,那么说明spring是不支持该注解用于依赖注入的,dubbo对此进行了支持该注册的拓展。

在入口@EnableDubbo配置了扫描的包路径

用于扫描类上含有dubbo@Service 和类属性上含有 @Reference 的bean

@DubboComponentScan 导入了DubboComponentScanRegistrar

DubboComponentScanRegistrar实现Spring的ImportBeanDefinitionRegistrar接口,被调用到实现的registerBeanDefinitions()时,会注册两个beanPostProcessor类

ReferenceAnnotationBeanPostProcessor实现了和spring中支持@Autowired注册的AutowiredAnnotationBeanPostProcessor一模一样的接口 :MergedBeanDefinitionPostProcessor,继承了InstantiationAwareBeanPostProcessorAdapter。两者的工作逻辑几乎一模一样。

在bean实例化之后,对 bean进行依赖注入

postProcessPropertyValues()

这个方法每个bean实例化都会调到,ReferenceAnnotationBeanPostProcessor用的是父握隐轿类AnnotationInjectedBeanPostProcessor的

判断方法和类上是否有@Reference注解,并将其包包装成AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata 对象,进行缓存

判断属性是否可以获取到@Reference,获取到返回

收集到需要依赖注入的属性之后,下一步获取到被依赖的bean实例,进行反射赋值

调用内部类AnnotatedFieldElement中的inject方法

获取到dubbo创建的代理实例,反射设置有@Reference的属性上

关于dubbo原理和dubbo原理和机制 面试的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

标签列表