Dubbo面试题(2021最新版)

基础知识

为何要用 Dubbo?

随着服务化的进一步发展,服务愈来愈多,服务之间的调用和依赖关系也愈来愈复杂,诞生了面向服务的架构体系(SOA),也所以衍生出了一系列相应的技术,如对服务提供、服务调用、链接处理、通讯协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。就这样为分布式系统的服务治理框架就出现了,Dubbo 也就这样产生了。javascript

Dubbo 是什么?

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

Dubbo 的使用场景有哪些?

  • 透明化的远程方法调用:就像调用本地方法同样调用远程方法,只需简单配置,没有任何API侵入。
  • 软负载均衡及容错机制:可在内网替代 F5 等硬件负载均衡器,下降成本,减小单点。
  • 服务自动注册与发现:再也不须要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,而且可以平滑添加或删除服务提供者。

Dubbo 核心功能有哪些?

  • Remoting:网络通讯框架,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。
  • Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
  • Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方能够平滑增长或减小机器。

架构设计

Dubbo 核心组件有哪些?

  • Provider:暴露服务的服务提供方
  • Consumer:调用远程服务消费方
  • Registry:服务注册与发现注册中心
  • Monitor:监控中心和访问调用统计
  • Container:服务运行容器

Dubbo 服务器注册与发现的流程?

服务容器Container负责启动,加载,运行服务提供者。java

服务提供者Provider在启动时,向注册中心注册本身提供的服务。web

服务消费者Consumer在启动时,向注册中心订阅本身所需的服务。算法

注册中心Registry返回服务提供者地址列表给消费者,若是有变动,注册中心将基于长链接推送变动数据给消费者。spring

服务消费者Consumer,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,若是调用失败,再选另外一台调用。apache

服务消费者Consumer和提供者Provider,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心Monitor。编程

Dubbo 的总体架构设计有哪些分层?

接口服务层(Service):该层与业务逻辑相关,根据 provider 和 consumer 的业务设计对应的接口和实现设计模式

配置层(Config):对外配置接口,以 ServiceConfig 和 ReferenceConfig 为中心浏览器

服务代理层(Proxy):服务接口透明代理,生成服务的客户端 Stub 和 服务端的 Skeleton,以 ServiceProxy 为中心,扩展接口为 ProxyFactory

服务注册层(Registry):封装服务地址的注册和发现,以服务 URL 为中心,扩展接口为 RegistryFactory、Registry、RegistryService

路由层(Cluster):封装多个提供者的路由和负载均衡,并桥接注册中心,以Invoker 为中心,扩展接口为 Cluster、Directory、Router 和 LoadBlancce

监控层(Monitor):RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory、Monitor 和 MonitorService

远程调用层(Protocal):封装 RPC 调用,以 Invocation 和 Result 为中心,扩展接口为 Protocal、Invoker 和 Exporter

信息交换层(Exchange):封装请求响应模式,同步转异步。以 Request 和Response 为中心,扩展接口为 Exchanger、ExchangeChannel、ExchangeClient 和 ExchangeServer

网络 传输 层(Transport):抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel、Transporter、Client、Server 和 Codec

数据序列化层(Serialize):可复用的一些工具,扩展接口为 Serialization、ObjectInput、ObjectOutput 和 ThreadPool

Dubbo Monitor 实现原理?

Consumer 端在发起调用以前会先走 filter 链;provider 端在接收到请求时也是先走 filter 链,而后才进行真正的业务逻辑处理。默认状况下,在 consumer 和 provider 的 filter 链中都会有 Monitorfilter。

一、MonitorFilter 向 DubboMonitor 发送数据

二、DubboMonitor 将数据进行聚合后(默认聚合 1min 中的统计数据)暂存到ConcurrentMap<Statistics, AtomicReference> statisticsMap,而后使用一个含有 3 个线程(线程名字:DubboMonitorSendTimer)的线程池每隔 1min 钟,调用 SimpleMonitorService 遍历发送 statisticsMap 中的统计数据,每发送完毕一个,就重置当前的 Statistics 的 AtomicReference

三、SimpleMonitorService 将这些聚合数据塞入 BlockingQueue queue 中(队列大写为 100000)

四、SimpleMonitorService 使用一个后台线程(线程名为:DubboMonitorAsyncWriteLogThread)将 queue 中的数据写入文件(该线程以死循环的形式来写)

五、SimpleMonitorService 还会使用一个含有 1 个线程(线程名字:DubboMonitorTimer)的线程池每隔 5min 钟,将文件中的统计数据画成图表

分布式框架

Dubbo 相似的分布式框架还有哪些?

比较著名的就是 Spring Cloud。

Dubbo 和 Spring Cloud 有什么关系?

Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。而 Spring Cloud 诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外因为依托了 Spring、Spring Boot 的优点之上,两个框架在开始目标就不一致,Dubbo 定位服务治理、Spring Cloud 是打造一个生态。

Dubbo 和 Spring Cloud 有什么哪些区别?

Dubbo 底层是使用 Netty 这样的 NIO 框架,是基于 TCP 协议传输的,配合以 Hession 序列化完成 RPC 通讯。

Spring Cloud 是基于 Http 协议 Rest 接口调用远程过程的通讯,相对来讲 Http 请求会有更大的报文,占的带宽也会更多。可是 REST 相比 RPC 更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更为合适,至于注重通讯速度仍是方便灵活性,具体状况具体考虑。

Dubbo 和 Dubbox 之间的区别?

Dubbox 是继 Dubbo 中止维护后,当当网基于 Dubbo 作的一个扩展项目,如加了服务可 Restful 调用,更新了开源组件等。

注册中心

Dubbo 有哪些注册中心?

  • Multicast 注册中心:Multicast 注册中心不须要任何中心节点,只要广播地址,就能进行服务注册和发现,基于网络中组播传输实现。
  • Zookeeper 注册中心:基于分布式协调系统 Zookeeper 实现,采用 Zookeeper 的 watch 机制实现数据变动。
  • Redis 注册中心:基于 Redis 实现,采用 key/map 存储,key 存储服务名和类型,map 中 key 存储服务 url,value 服务过时时间。基于 Redis 的发布/订阅模式通知数据变动。
  • Simple 注册中心。

推荐使用 Zookeeper 做为注册中心

Dubbo 的注册中心集群挂掉,发布者和订阅者之间还能通讯么?

能够通信。启动 Dubbo 时,消费者会从 Zookeeper 拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用。

集群

Dubbo集群提供了哪些负载均衡策略?

  • Random LoadBalance: 随机选取提供者策略,有利于动态调整提供者权重。截面碰撞率高,调用次数越多,分布越均匀。
  • RoundRobin LoadBalance: 轮循选取提供者策略,平均分布,可是存在请求累积的问题。
  • LeastActive LoadBalance: 最少活跃调用策略,解决慢提供者接收更少的请求。
  • ConstantHash LoadBalance: 一致性 Hash 策略,使相同参数请求老是发到同一提供者,一台机器宕机,能够基于虚拟节点,分摊至其余提供者,避免引发提供者的剧烈变更。

默认为 Random 随机调用。

Dubbo的集群容错方案有哪些?

  • Failover Cluster:失败自动切换,当出现失败,重试其它服务器。一般用于读操做,但重试会带来更长延迟。
  • Failfast Cluster:快速失败,只发起一次调用,失败当即报错。一般用于非幂等性的写操做,好比新增记录。
  • Failsafe Cluster:失败安全,出现异常时,直接忽略。一般用于写入审计日志等操做。
  • Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。一般用于消息通知操做。
  • Forking Cluster:并行调用多个服务器,只要一个成功即返回。一般用于实时性要求较高的读操做,但须要浪费更多服务资源。可经过 forks=”2″ 来设置最大并行数。
  • Broadcast Cluster:广播调用全部提供者,逐个调用,任意一台报错则报错 。一般用于通知全部提供者更新缓存或日志等本地资源信息。

默认的容错方案是 Failover Cluster。

配置

Dubbo 配置文件是如何加载到 Spring 中的?

Spring 容器在启动的时候,会读取到 Spring 默认的一些 schema 以及 Dubbo 自定义的 schema,每一个 schema 都会对应一个本身的 NamespaceHandler,NamespaceHandler 里面经过 BeanDefinitionParser 来解析配置信息并转化为须要加载的 bean 对象!

说说核心的配置有哪些?

标签 用途 解释
<dubbo:service/> 服务配置 用于暴露一个服务,定义服务的元信息,一个服务能够用多个协议暴露,一个服务也能够注册到多个注册中心
<dubbo:reference/> 引用配置 用于建立一个远程服务代理,一个引用能够指向多个注册中心
<dubbo:protocol/> 协议配置 用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受
<dubbo:application/> 应用配置 用于配置当前应用信息,无论该应用是提供者仍是消费者
<dubbo:module/> 模块配置 用于配置当前模块信息,可选
<dubbo:registry/> 注册中心配置 用于配置链接注册中心相关信息
<dubbo:monitor/> 监控中心配置 用于配置链接监控中心相关信息,可选
<dubbo:provider/> 提供方配置 当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选
<dubbo:consumer/> 消费方配置 当 ReferenceConfig 某属性没有配置时,采用此缺省值,可选
<dubbo:method/> 方法配置 用于 ServiceConfig 和 ReferenceConfig 指定方法级的配置信息
<dubbo:argument/> 参数配置 用于指定方法参数配置

Dubbo 超时设置有哪些方式?

Dubbo 超时设置有两种方式:

  • 服务提供者端设置超时时间,在Dubbo的用户文档中,推荐若是能在服务端多配置就尽可能多配置,由于服务提供者比消费者更清楚本身提供的服务特性。
  • 服务消费者端设置超时时间,若是在消费者端设置了超时时间,以消费者端为主,即优先级更高。由于服务调用方设置超时时间控制性更灵活。若是消费方超时,服务端线程不会定制,会产生警告。

服务调用超时会怎么样?

dubbo 在调用服务不成功时,默认是会重试两次。

通讯协议

Dubbo 使用的是什么通讯框架?

默认使用 Netty 做为通信框架。

Dubbo 支持哪些协议,它们的优缺点有哪些?

  • Dubbo: 单一长链接和 NIO 异步通信,适合大并发小数据量的服务调用,以及消费者远大于提供者。传输协议 TCP,异步 Hessian 序列化。Dubbo推荐使用dubbo协议
  • RMI: 采用 JDK 标准的 RMI 协议实现,传输参数和返回参数对象须要实现 Serializable 接口,使用 Java 标准序列化机制,使用阻塞式短链接,传输数据包大小混合,消费者和提供者个数差很少,可传文件,传输协议 TCP。 多个短链接 TCP 协议传输,同步传输,适用常规的远程服务调用和 RMI 互操做。在依赖低版本的 Common-Collections 包,Java 序列化存在安全漏洞。
  • WebService:基于 WebService 的远程调用协议,集成 CXF 实现,提供和原生 WebService 的互操做。多个短链接,基于 HTTP 传输,同步传输,适用系统集成和跨语言调用。
  • HTTP: 基于 Http 表单提交的远程调用协议,使用 Spring 的 HttpInvoke 实现。多个短链接,传输协议 HTTP,传入参数大小混合,提供者个数多于消费者,须要给应用程序和浏览器 JS 调用。
  • Hessian:集成 Hessian 服务,基于 HTTP 通信,采用 Servlet 暴露服务,Dubbo 内嵌 Jetty 做为服务器时默认实现,提供与 Hession 服务互操做。多个短链接,同步 HTTP 传输,Hessian 序列化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件。
  • Memcache:基于 Memcache实现的 RPC 协议。
  • Redis:基于 Redis 实现的RPC协议。

设计模式

Dubbo 用到哪些设计模式?

Dubbo 框架在初始化和通讯过程当中使用了多种设计模式,可灵活控制类加载、权限控制等功能。

工厂模式

Provider 在 export 服务时,会调用 ServiceConfig 的 export 方法。ServiceConfig中有个字段:

private static final Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtensi
on();

Dubbo 里有不少这种代码。这也是一种工厂模式,只是实现类的获取采用了 JDKSPI 的机制。这么实现的优势是可扩展性强,想要扩展实现,只须要在 classpath下增长个文件就能够了,代码零侵入。另外,像上面的 Adaptive 实现,能够作到调用时动态决定调用哪一个实现,可是因为这种实现采用了动态代理,会形成代码调试比较麻烦,须要分析出实际调用的实现类。

装饰器模式

Dubbo 在启动和调用阶段都大量使用了装饰器模式。以 Provider 提供的调用链为例,具体的调用链代码是在 ProtocolFilterWrapper 的 buildInvokerChain 完成的,具体是将注解中含有 group=provider 的 Filter 实现,按照 order 排序,最后的调用顺序是:

EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter ->
ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter ->
ExceptionFilter

更确切地说,这里是装饰器和责任链模式的混合使用。例如,EchoFilter 的做用是判断是不是回声测试请求,是的话直接返回内容,这是一种责任链的体现。而像ClassLoaderFilter 则只是在主功能上添加了功能,更改当前线程的 ClassLoader,这是典型的装饰器模式。

观察者模式

Dubbo 的 Provider 启动时,须要与注册中心交互,先注册本身的服务,再订阅本身的服务,订阅时,采用了观察者模式,开启一个 listener。注册中心会每 5 秒定时检查是否有服务更新,若是有更新,向该服务的提供者发送一个 notify 消息,provider 接受到 notify 消息后,运行 NotifyListener 的 notify 方法,执行监听器方法。

动态代理模式

Dubbo 扩展 JDK SPI 的类 ExtensionLoader 的 Adaptive 实现是典型的动态代理实现。Dubbo 须要灵活地控制实现类,即在调用阶段动态地根据参数决定调用哪一个实现类,因此采用先生成代理类的方法,可以作到灵活的调用。生成代理类的代码是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法。代理类主要逻辑是,获取 URL 参数中指定参数的值做为获取实现类的 key。

运维管理

服务上线怎么兼容旧版本?

能够用版本号(version)过渡,多个不一样版本的服务注册到注册中心,版本号不一样的服务相互间不引用。这个和服务分组的概念有一点相似。

Dubbo telnet 命令能作什么?

dubbo 服务发布以后,咱们能够利用 telnet 命令进行调试、管理。Dubbo2.0.5 以上版本服务提供端口支持 telnet 命令

Dubbo 支持服务降级吗?

以经过 dubbo:reference 中设置 mock=“return null”。mock 的值也能够修改成 true,而后再跟接口同一个路径下实现一个 Mock 类,命名规则是 “接口名称+Mock” 后缀。而后在 Mock 类里实现本身的降级逻辑

Dubbo 如何优雅停机?

Dubbo 是经过 JDK 的 ShutdownHook 来完成优雅停机的,因此若是使用kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有经过 kill PID 时,才会执行。

SPI

Dubbo SPI 和 Java SPI 区别?

JDK SPI

JDK 标准的 SPI 会一次性加载全部的扩展实现,若是有的扩展很耗时,但也没用上,很浪费资源。因此只但愿加载某个的实现,就不现实了

DUBBO SPI

一、对 Dubbo 进行扩展,不须要改动 Dubbo 的源码

二、延迟加载,能够一次只加载本身想要加载的扩展实现。

三、增长了对扩展点 IOC 和 AOP 的支持,一个扩展点能够直接 setter 注入其

它扩展点。

四、Dubbo 的扩展机制能很好的支持第三方 IoC 容器,默认支持 Spring Bean。

其余

Dubbo 支持分布式事务吗?

目前暂时不支持,可与经过 tcc-transaction 框架实现

介绍:tcc-transaction 是开源的 TCC 补偿性分布式事务框架

TCC-Transaction 经过 Dubbo 隐式传参的功能,避免本身对业务代码的入侵。

Dubbo 能够对结果进行缓存吗?

为了提升数据访问的速度。Dubbo 提供了声明式缓存,以减小用户加缓存的工做量<dubbo:reference cache=“true” />

其实比普通的配置文件就多了一个标签 cache=“true”

Dubbo 必须依赖的包有哪些?

Dubbo 必须依赖 JDK,其余为可选。

Dubbo 支持哪些序列化方式?

默认使用 Hessian 序列化,还有 Duddo、FastJson、Java 自带序列化。

Dubbo 在安全方面有哪些措施?

  • Dubbo 经过 Token 令牌防止用户绕过注册中心直连,而后在注册中心上管理受权。
  • Dubbo 还提供服务黑白名单,来控制服务所容许的调用方。

服务调用是阻塞的吗?

默认是阻塞的,能够异步调用,没有返回值的能够这么作。Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不须要启动多线程便可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。

服务提供者能实现失效踢出是什么原理?

服务失效踢出基于 zookeeper 的临时节点原理。

同一个服务多个注册的状况下能够直连某一个服务吗?

能够点对点直连,修改配置便可,也能够经过 telnet 直接某个服务。

Dubbo 服务降级,失败重试怎么作?

能够经过 dubbo:reference 中设置 mock=“return null”。mock 的值也能够修改成 true,而后再跟接口同一个路径下实现一个 Mock 类,命名规则是 “接口名称+Mock” 后缀。而后在 Mock 类里实现本身的降级逻辑

Dubbo 使用过程当中都遇到了些什么问题?

在注册中心找不到对应的服务,检查 service 实现类是否添加了@service 注解没法链接到注册中心,检查配置文件中的对应的测试 ip 是否正确

RPC

为何要有RPC

http接口是在接口很少、系统与系统交互较少的状况下,解决信息孤岛初期常使用的一种通讯手段;优势就是简单、直接、开发方便。利用现成的http协议进行传输。可是若是是一个大型的网站,内部子系统较多、接口很是多的状况下,RPC框架的好处就显示出来了,首先就是长连接,没必要每次通讯都要像http同样去3次握手什么的,减小了网络开销;其次就是RPC框架通常都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来讲是无感知、统一化的操做。第三个来讲就是安全性。最后就是最近流行的服务化架构、服务化治理,RPC框架是一个强力的支撑。

socket只是一个简单的网络通讯方式,只是建立通讯双方的通讯通道,而要实现rpc的功能,还须要对其进行封装,以实现更多的功能。

RPC通常配合netty框架、spring自定义注解来编写轻量级框架,其实netty内部是封装了socket的,较新的jdk的IO通常是NIO,即非阻塞IO,在高并发网站中,RPC的优点会很明显

什么是RPC

RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。简言之,RPC使得程序可以像访问本地系统资源同样,去访问远端系统资源。比较关键的一些方面包括:通信协议、序列化、资源(接口)描述、服务框架、性能、语言支持等。

简单的说,RPC就是从一台机器(客户端)上经过参数传递的方式调用另外一台机器(服务器)上的一个函数或方法(能够统称为服务)并获得返回的结果。

PRC架构组件

一个基本的RPC架构里面应该至少包含如下4个组件:

一、客户端(Client):服务调用方(服务消费者)

二、客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再经过网络传输发送给服务端

三、服务端存根(Server Stub):接收客户端发送过来的请求消息并进行解包,而后再调用本地服务进行处理

四、服务端(Server):服务的真正提供者

具体调用过程

一、服务消费者(client客户端)经过调用本地服务的方式调用须要消费的服务;

二、客户端存根(client stub)接收到调用请求后负责将方法、入参等信息序列化(组装)成可以进行网络传输的消息体;

三、客户端存根(client stub)找到远程的服务地址,而且将消息经过网络发送给服务端;

四、服务端存根(server stub)收到消息后进行解码(反序列化操做);

五、服务端存根(server stub)根据解码结果调用本地的服务进行相关处理;

六、本地服务执行具体业务逻辑并将处理结果返回给服务端存根(server stub);

七、服务端存根(server stub)将返回结果从新打包成消息(序列化)并经过网络发送至消费方;

八、客户端存根(client stub)接收到消息,并进行解码(反序列化);

九、服务消费方获得最终结果;

而RPC框架的实现目标则是将上面的第2-10步无缺地封装起来,也就是把调用、编码/解码的过程给封装起来,让用户感受上像调用本地服务同样的调用远程服务。

RPC和SOA、SOAP、REST的区别

一、REST

能够看着是HTTP协议的一种直接应用,默认基于JSON做为传输格式,使用简单,学习成本低效率高,可是安全性较低。

二、SOAP

SOAP是一种数据交换协议规范,是一种轻量的、简单的、基于XML的协议的规范。而SOAP能够看着是一个重量级的协议,基于XML、SOAP在安全方面是经过使用XML-Security和XML-Signature两个规范组成了WS-Security来实现安全控制的,当前已经获得了各个厂商的支持 。

它有什么优势?简单总结为:易用、灵活、跨语言、跨平台。

三、SOA

面向服务架构,它能够根据需求经过网络对松散耦合的粗粒度应用组件进行分布式部署、组合和使用。服务层是SOA的基础,能够直接被应用调用,从而有效控制系统中与软件代理交互的人为依赖性。

SOA是一种粗粒度、松耦合服务架构,服务之间经过简单、精肯定义接口进行通信,不涉及底层编程接口和通信模型。SOA能够看做是B/S模型、XML(标准通用标记语言的子集)/Web Service技术以后的天然延伸。

四、REST 和 SOAP、RPC 有何区别呢?

没什么太大区别,他们的本质都是提供可支持分布式的基础服务,最大的区别在于他们各自的的特色所带来的不一样应用场景 。

RPC框架须要解决的问题?

一、如何肯定客户端和服务端之间的通讯协议?

二、如何更高效地进行网络通讯?

三、服务端提供的服务如何暴露给客户端?

四、客户端如何发现这些暴露的服务?

五、如何更高效地对请求对象和响应结果进行序列化和反序列化操做?

RPC的实现基础?

一、须要有很是高效的网络通讯,好比通常选择Netty做为网络通讯框架;

二、须要有比较高效的序列化框架,好比谷歌的Protobuf序列化框架;

三、可靠的寻址方式(主要是提供服务的发现),好比可使用Zookeeper来注册服务等等;

四、若是是带会话(状态)的RPC调用,还须要有会话和状态保持的功能;

RPC使用了哪些关键技术?

一、动态代理

生成Client Stub(客户端存根)和Server Stub(服务端存根)的时候须要用到Java动态代理技术,可使用JDK提供的原生的动态代理机制,也可使用开源的:CGLib代理,Javassist字节码生成技术。

二、序列化和反序列化

在网络中,全部的数据都将会被转化为字节进行传送,因此为了可以使参数对象在网络中进行传输,须要对这些参数进行序列化和反序列化操做。

  • 序列化:把对象转换为字节序列的过程称为对象的序列化,也就是编码的过程。
  • 反序列化:把字节序列恢复为对象的过程称为对象的反序列化,也就是解码的过程。

目前比较高效的开源序列化框架:如Kryo、FastJson和Protobuf等。

三、NIO通讯

出于并发性能的考虑,传统的阻塞式 IO 显然不太合适,所以咱们须要异步的 IO,即 NIO。Java 提供了 NIO 的解决方案,Java 7 也提供了更优秀的 NIO.2 支持。能够选择Netty或者MINA来解决NIO数据传输的问题。

四、服务注册中心

可选:Redis、Zookeeper、Consul 、Etcd。通常使用ZooKeeper提供服务注册与发现功能,解决单点故障以及分布式部署的问题(注册中心)。

主流RPC框架有哪些

一、RMI

利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol) 和java的原生序列化。

二、Hessian

是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 基于HTTP协议,采用二进制编解码。

三、protobuf-rpc-pro

是一个Java类库,提供了基于 Google 的 Protocol Buffers 协议的远程方法调用的框架。基于 Netty 底层的 NIO 技术。支持 TCP 重用/ keep-alive、SSL加密、RPC 调用取消操做、嵌入式日志等功能。

四、Thrift

是一种可伸缩的跨语言服务的软件框架。它拥有功能强大的代码生成引擎,无缝地支持C + +,C#,Java,Python和PHP和Ruby。thrift容许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通讯代码。

最初由facebook开发用作系统内个语言之间的RPC通讯,2007年由facebook贡献到apache基金 ,如今是apache下的opensource之一 。支持多种语言之间的RPC方式的通讯:php语言client能够构造一个对象,调用相应的服务方法来调用java语言的服务,跨越语言的C/S RPC调用。底层通信基于SOCKET。

五、Avro

出自Hadoop之父Doug Cutting, 在Thrift已经至关流行的状况下推出Avro的目标不只是提供一套相似Thrift的通信中间件,更是要创建一个新的,标准性的云计算的数据交换和存储的Protocol。支持HTTP,TCP两种协议。

六、Dubbo

Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可经过高性能的 RPC 实现服务的输出和输入功能,能够和 Spring框架无缝集成。

RPC的实现原理架构图

PS:这张图很是重点,是PRC的基本原理,请你们必定记住!

也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,因为不在一个内存空间,不能直接调用,须要经过网络来表达调用的语义和传达调用的数据。

好比说,A服务器想调用B服务器上的一个方法:

User getUserByName(String userName)

一、创建通讯

首先要解决通信的问题:即A机器想要调用B机器,首先得创建起通讯链接。

主要是经过在客户端和服务器之间创建TCP链接,远程过程调用的全部交换的数据都在这个链接里传输。链接能够是按需链接,调用结束后就断掉,也能够是长链接,多个远程过程调用共享同一个链接。

一般这个链接能够是按需链接(须要调用的时候就先创建链接,调用结束后就立马断掉),也能够是长链接(客户端和服务器创建起链接以后保持长期持有,无论此时有无数据包的发送,能够配合心跳检测机制按期检测创建的链接是否存活有效),多个远程过程调用共享同一个链接。

二、服务寻址

要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层的RPC框架,如何链接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么。

一般状况下咱们须要提供B机器(主机名或IP地址)以及特定的端口,而后指定调用的方法或者函数的名称以及入参出参等信息,这样才能完成服务的一个调用。

可靠的寻址方式(主要是提供服务的发现)是RPC的实现基石,好比能够采用Redis或者Zookeeper来注册服务等等。

img

2.一、从服务提供者的角度看

当服务提供者启动的时候,须要将本身提供的服务注册到指定的注册中心,以便服务消费者可以经过服务注册中心进行查找;

当服务提供者因为各类缘由导致提供的服务中止时,须要向注册中心注销中止的服务;

服务的提供者须要按期向服务注册中心发送心跳检测,服务注册中心若是一段时间未收到来自服务提供者的心跳后,认为该服务提供者已经中止服务,则将该服务从注册中心上去掉。

2.二、从调用者的角度看

服务的调用者启动的时候根据本身订阅的服务向服务注册中心查找服务提供者的地址等信息;

当服务调用者消费的服务上线或者下线的时候,注册中心会告知该服务的调用者;

服务调用者下线的时候,则取消订阅。

三、网络传输

3.一、序列化

当A机器上的应用发起一个RPC调用时,调用方法和其入参等信息须要经过底层的网络协议如TCP传输到B机器,因为网络协议是基于二进制的,全部咱们传输的参数数据都须要先进行序列化(Serialize)或者编组(marshal)成二进制的形式才能在网络中进行传输。而后经过寻址操做和网络传输将序列化或者编组以后的二进制数据发送给B机器。

3.二、反序列化

当B机器接收到A机器的应用发来的请求以后,又须要对接收到的参数等信息进行反序列化操做(序列化的逆操做),即将二进制信息恢复为内存中的表达方式,而后再找到对应的方法(寻址的一部分)进行本地调用(通常是经过生成代理Proxy去调用, 一般会有JDK动态代理、CGLIB动态代理、Javassist生成字节码技术等),以后获得调用的返回值。

四、服务调用

B机器进行本地调用(经过代理Proxy和反射调用)以后获得了返回值,此时还须要再把返回值发送回A机器,一样也须要通过序列化操做,而后再通过网络传输将二进制数据发送回A机器,而当A机器接收到这些返回值以后,则再次进行反序列化操做,恢复为内存中的表达方式,最后再交给A机器上的应用进行相关处理(通常是业务逻辑处理操做)。

一般,通过以上四个步骤以后,一次完整的RPC调用算是完成了,另外可能由于网络抖动等缘由须要重试等。

来源:https://thinkwon.blog.csdn.net/

做者:thinkwon

本文首发于公众号:Java版web项目,欢迎关注获取更多精彩内容
相关文章
相关标签/搜索