• 轻量级RPC框架‘dubbo’


    Dobbo面试题整理

    1、什么是Dubbo?

    Dubbo 是一款高性能、轻量级的开源 RPC 框架,提供服务自动注册、自动发现等高效服务治理方案, 可以和 Spring 框架集成。

    2、为什么使用Dubbo?

    随着服务的发展,服务越来越多,因此服务之间的调用和依赖关系也越来越复杂,从而衍生出了SOA(面向服务的架构体系),对服务提供、服务调用、连接处理、序列化方式、服务发现、服务路由等进行封装的服务框架,于是乎,分布式系统服务治理框架就出现了,Dubbo也由此诞生。

    3、Dubbo工作原理?

    3.1 Dubbo核心组件

    在这里插入图片描述

    • Provider:服务提供方
    • Consumer:调用远程服务消费方
    • Registry:服务注册与发现注册中心
    • Monitor:监控中心
    • Container:服务运行容器

    3.2 Dubbo执行流程

    • 当服务启动的时候,provider和consumer根据配置信息,连接到注册中心register,分别向注册中心注册和订阅服务
    • register根据服务订阅关系,返回provider信息到consumer,同时consumer会把provider信息缓存到本地,如果信息发生变化,consumer会收到来自register的推送信息。
    • consumer生成代理对象,同时根据负载均衡策略,选择一台provider,同时定时向monitor记录接口的调用次数和时间信息。
    • 拿到代理对象之后,consumer通过代理对象发起接口调用
    • provider收到请求后对数据进行反序列化,然后通过代理调用具体的接口实现

    4、Dubbo分层

    Dubbo从大范围可分为三层,Business业务层,RPC层,Remoting层

    1、Business业务层

    主要用来提供接口和实现的一些配置信息

    2、RPC层

    核心层,主要用来封装整个RPC的调用过程、负载均衡、集群容错、代理和远程调用

    3、Remoting层

    主要用来对网络传输协议和数据转换的封装

    img

    5、服务调用是阻塞的吗?

    默认是阻塞,但是可以异步调用,Dubbo是基于NIO的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,因此多线程开销较小,异步调用的时候会返回一个future对象。

    6、集群容错方式有哪些?

    Dubbo容错方案说明
    Failover Cluster**(默认)**失败自动切换,自动重试其他服务器
    Failback Cluster失败自动恢复,记录失败请求,定时重发
    Failfast Cluster快速失败,立即报错,只发起一次调用
    Failsafe Cluster失败安全,出现异常,直接忽略
    Forking Cluster并行调用多个服务提供者,只要一次成功即可返回
    Broadcast Cluster广播模式,逐步调用每一个provider,如果其中一台报错,调用结束之后,会抛出异常

    7、Dubbo SPI机制

    SPI(service provider Interface)是一种服务发现机制,本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类,这样可以在运行时,动态为接口替换实现类。

    • 对Dubbo进行扩展,包括协议扩展、集群扩展、路由扩展、序列化扩展等等,此时不需要改动Dubbo源码

    • 延迟加载,可以一次只加载自己想要加载的扩展实现

    • Dubbo的扩展机制很好的支持第三方IOC容器,默认支持Spring bean

    • 修改META-INF/dubbo目录下的配置,通过dubbo的ExtensionLoader按照指定的key加载对应的实现类,这样做的好处就是可以按需加载,性能上得到优化。

    key=com.XXX.value
    
    • 1

    8、如何设计一个RPC框架

    1、首先需要有一个注册中心,这样consumer和provider才能去注册和订阅服务

    2、需要负载均衡的机制解决consumer如何调用客户端,其中也包括容错、重试机制

    3、需要通信协议和工具框架,比如说通过http协议通信,然后根据协议选择使用什么框架和工具来进行通信,此外,数据传输也需要考虑序列化等等因素。

    4、还需要一些监控、配置管理页面的服务

    9、序列化框架

    • Hessian
    • Dubbo
    • fastJson
    • Java自带序列化框架

    10、Dubbo注册中心

    一般推荐使用Zookeeper作为注册中心,Multicast,Redis一般不推荐使用。

    11、Dubbo通信机制

    Dubbo采用的是Netty框架通信,一般要通过代理对象通信。

    11.1、Netty是什么?

    Netty 是一个基于NIO的客户、服务器端编程框架,Netty提供异步的,事件驱动的网络应用程序框架和工具,可以快速开发高可用的客户端和服务器。Netty是基于NIO的,它封装了JDK的NIO,让我们使用起来更加方法灵活。

    11.2 比较NIO与传统IO优缺点

    传统IO(BIO 同步并阻塞)
    传统IO中,每创建一个连接都要创建一个线程来维护,极大地浪费资源和增加服务器的压力,即创建的线程如果不做任何处理就会造成不必要的线程开销。
    
    BIO适用场景
    - 用于连接数目比较小且固定的框架 在jdk1.4之前选择使用
    
    • 1
    • 2
    • 3
    • 4
    • 5

    BIO工作流程
    在这里插入图片描述

    NIO模型(同步非阻塞)
    NIO模型中,服务端实现模式为每一个线程处理多个请求,即客户端发送的请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求处理,NIO有三大核心部分:channel(通道)、Buffer(缓冲区)、selecter(选择器)
    NIO服务模式:使一个线程从某通道发送请求或者读取数据,但是它仅仅能得到目前可用的数据,若果是无用数据,将不会获取,也不会阻塞。
    
    NIO适用场景
    NIO方式适用于连接数目多且连接比较大的架构,例如:相册服务器,在jdk 1.7之前选择使用
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    NIO工作流程

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-57JYxqr4-1660489907395)(C:\Users\geticsen\AppData\Roaming\Typora\typora-user-images\image-20220622213646626.png)]

    11.3、BIO/NIO比较

    • BIO基于字节流和字符流进行操作,而NIO以块的方式处理数据,块处理效率比BIO高

    • BIO是阻塞的,NIO是非阻塞的

    12、Dubbo实现服务降级

    12.1、什么是服务降级?

    使用Dubbo在进行服务调用的时候,由于各种原因(网络时延、服务器宕机、并发过高),调用就会出现RpcException,导致调用失败。服务降级就是指在服务不可用时,可以返回默认值,避免异常影响主业务的处理。

    12.2 、Dubbo服务降级配置

    dubbo官网中使用一个mock配置,是实现服务降级。

    方案一:

    服务提供方接口:

    /**接口定义*/
    public interface StudentService {
     
        public void doSomething1();
     
        public String doSomething2(String str);
     
    }
     
    /**实现类*/
    public class StudentServiceImpl implements StudentService {
     
        public void doSomething1() {
            System.out.println("service invoke: doSomething1");
        }
     
        public String doSomething2(String str) {
            System.out.println("service invoke: doSomething2 ," + str);
            return "service invoke: doSomething2";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    服务提供方dubbo.xml

    
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
        <dubbo:application name="hello-world-app" />
     
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
     
        <dubbo:protocol name="dubbo" port="20880" />
     
        <dubbo:service interface="com.sun.service.StudentService" ref="StudentServiceImpl" timeout="10000" />
     
        
        <bean id="StudentServiceImpl" class="com.sun.serviceimpl.StudentServiceImpl" />
     
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    服务调用方:

    
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
     
        <dubbo:application name="dubbo-consumer"/>
     
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
     
        <dubbo:reference id="StudentService" interface="com.sun.service.StudentService"  timeout="10000" check="false" mock="return null">
        dubbo:reference>
     
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试在调用端调用服务两个方法,当服务端正常启动时,程序获得正常返回值;当服务提供方出现异常,调用方依然正常运行,调用doSomething2获取返回值时null。

    方案二:mock实现接口方式

    上面在**dubbuo:reference 中配置mock=“retrun null” 的配置**,在服务降级时会对service中的所有方法做统一处理,即都返回null。

    但是有的时候我们需要一些方法在服务不可用时告诉我们一些其他信息,以便做其他处理。如更新/删除等。此时,可以通过以下的方式。

    业务接口所在的包中,定义一个类,该类的命名需要满足以下规则:

    • 业务接口简单类名 + Mock同时实现mock接口
    • 类名要注意命名规范:接口名+Mock后缀,此时如果调用失败会调用Mock实现,mock实现需要保证有无参的构造方法。

    配置mock=”true”的情况,对于上面的例子即在StudentService的同个路径下,添加类StudentServiceMock,实现如下:

    public class StudentServiceMock implements StudentService {
        public void doSomething1() {
            throw new RuntimeException("fail!");
        }
     
        public String doSomething2(String str) {
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    修改消费者dubbo.xml

     <dubbo:reference id="StudentService" interface="com.sun.service.StudentService"  timeout="10000" check="false" mock="true">
    
    • 1

    参考资料:
    https://dubbo.incubator.apache.org/zh/overview/what/overview/

  • 相关阅读:
    人大金仓分析型数据库JSON索引
    Oracle 11g+PLSQL Developer安装及环境配置
    如何在小程序中实现页面之间的跳转
    Effective Java学习笔记---------通用编程
    【Python】Python中的lambda表达式
    SpringBoot+Mybatis实现多数据源+分页
    Linux之高级IO相关内容整理分析
    深度神经网络算法有哪些,python深度神经网络算法
    uniapp-video自定义视频封面
    史上最全ubuntu18.04安装教程|搜狗输入法配置教程|网络配置|相关命令配置
  • 原文地址:https://blog.csdn.net/an760998254/article/details/126338104