主题
Dubbo 面试题
基础知识
1.为什么要用 Dubbo?
随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系 (SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。就这样为分布式系统的服务治理框架就出现了,Dubbo 也就这样产生了。
2.Dubbo 是什么?
Dubbo 是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目。致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
简单的说,dubbo 就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有 dubbo 这样的分布式服务框架的需求,并且本质上是个服务调用的东西,说白了就是个远程服务调用的分布式框架(告别 Web Service 模式中的 WSdl,以服务者与消费者的方式在 dubbo 上注册)
其核心部分包含:
1.远程通讯:提供对多种基于长连接的 NIO 框架抽象封装,包括多种线程模型,序列化,以及 " 请求-响应 " 模式的信息交换。
2.集群容错:提供基于接口方法的透明远程过程调用,包括协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3.自动发现:基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
3.Dubbo 的使用场景有哪些?
- 透明化的远程调用:就像调用本地方法一样调用远程方法,只需要简单配置,没有任何 API 侵入。
- 软负载均衡容错机制:可在内网替代 F5 等硬件负载均衡器,降低成本,减少单点。
- 服务自动注册与发现:不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的 IP 地址,并且能够平滑添加或删除服务提供者
例:
1.RPC 分布式服务
当网站变大后,不可避免的需要拆分应用进行服务化,以提高开发效率,调优性能,节省关键竞争资源等。
比如:为了适用不断变化的市场需求,以及多个垂直应用之间数据交互方便,我们把公共的业务抽取出来作为独立的模块,为其他的应用提供服务,系统逐渐依赖于抽象和 rpc 远程服务调用。
2.配置管理
当服务越来越多时,服务的 URL 地址信息就会爆炸式增长,配置管理变得非常困难,F5 硬件负载均衡器的单点压力也越来越大。
3.服务依赖
当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
4.服务扩容
接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?等等……
4.Dubbo 核心功能有哪些?
主要有如下 3 个核心功能:
1.remoting:网络通信框架,提供对多种 NIO 框架抽象封装,包括 " 同步转异步 " 和 " 请求-响应 " 模式的信息交换方式。
2.Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3.Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器
架构设计
5.Dubbo 核心组件有哪些?
| 组件角色 | 说明 |
|---|---|
| Provider | 暴露服务的服务提供方 |
| Consumer | 调用远程服务的服务消费方 |
| Registry | 服务注册与发现的注册中心 |
| Monitor | 统计服务的调用次调和调用时间的监控中心 |
| Container | 服务运行容器 |
6.Dubbo 服务器注册与发现的流程?

7.Dubbo 的整体架构设计有哪些分层?

Dubbo 大的三层分别为 Business(业务层)、RPC 层、Remoting,并且还分为 API 层和 SPI 层。
分为大三层其实就是和我们知道的网络分层一样的意思,只有层次分明,职责边界清晰才能更好的扩展。
而分 API 层和 SPI 层这是 Dubbo 成功的一点,采用微内核设计 +SPI 扩展,使得有特殊需求的接入方可以自定义扩展,做定制的二次开发。
Dubbo 整体架构分为 10 小层:
- Service,业务层,该层与业务逻辑相关,格局 provider 和 consumer 的业务设计对应的接口和实现。
- Config,配置层,对外配置接口,以 ServiceConfig 和 ReferenceConfig 为中心
- Proxy,服务提供者还是消费者都会生成一个代理类,使得服务接口透明化,代理层做远程调用和返回结果。
- Register,注册层, 封 装 服 务 地 址 的 注 册 和 发 现
- Cluster,路由和集群容错层,负责选取具体调用的节点,处理特殊的调用要求和负责远程调用失败的容错措施。
- Monitor,监控层, RPC 调用次数和调用时间监控
- Portocol,远程调用层,远程调用层,主要是封装 RPC 调用,主要负责管理 Invoker,Invoker 代表一个抽象封装了的执行体,之后再做详解
- Exchange,信息交换层,用来封装请求响应模式,同步转异步。
- Transport,网络传输层,抽 象 mina 和 netty 为 统 一 接口 ,以 Message 为中 心 , 扩 展 接 口 为 Channel、 Transporter、 Client、 Server 和 Codec
- Serialize,序列化层,序列化层,将数据序列化成二进制流,当然也做反序列化。
8.Dubbo Monitor 实现原理?
Consumer 端在发起调用之前会先走 filter 链;provider 端在接收到请求时也是先走 filter 链,然后才进行真正的业务逻辑处理。
默认情况下,在 consumer 和 provider 的 filter 链中都会有 Monitorfilter。
1、MonitorFilter 向 DubboMonitor 发送数据
2、DubboMonitor 将数据进行聚合后(默认聚合 1min 中的统计数据)暂存到 ConcurrentMap<Statistics, AtomicReference> statisticsMap,然后使用一个含有 3 个线程(线程名字:DubboMonitorSendTimer)的线程池每隔 1min 钟,调用 SimpleMonitorService 遍历发送 statisticsMap 中的统计数据,每发送完毕一个,就重置当前的 Statistics 的 AtomicReference
3、SimpleMonitorService 将这些聚合数据塞入 BlockingQueue queue 中(队列大写为 100000)
4、SimpleMonitorService 使用一个后台线程(线程名为:DubboMonitorAsyncWriteLogThread)将 queue 中的数据写入文件(该线程以死循环的形式来写)
5、SimpleMonitorService 还会使用一个含有 1 个线程(线程名字:DubboMonitorTimer)的线程池每隔 5min 钟,将文件中的统计数据画成图表
分布式框架
9.Dubbo 类似的分布式框架还有哪些?
还有 spring 的 spring cloud, facebook 的 thrift, twitter 的 finagle 等
10.Dubbo 和 Spring Cloud 有什么关系?
Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。而 SpringCloud 诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外由于依托了 Spirng、SpirngBoot 的优势之上,两个框架在开始目标就不一致,Dubbo 定位服务治理、SpirngCloud 是一个生态。
11.Dubbo 和 Spring Cloud 有什么哪些区别?
| Dubbo | Spring Cloud | |
|---|---|---|
| 服务注册中心 | ZooKeeper | Spring Cloud Netflix Eureka |
| 服务调用方式 | RPC | RestFul |
| 服务网关 | 无 | Spring Cloud Netflix Zuul |
| 断路由 | 不完善 | Spring Cloud Netflix Hystrix |
| 分布式配置 | 无 | Spring Cloud Config |
| 服务跟踪 | 无 | Spring Cloud Sleuth |
| 消息总线 | 无 | Spring Cloud Bus |
| 数据流 | 无 | Spring Cloud Stream |
| 批量任务 | 无 | Spring Cloud Task |
12.Dubbo 和 Dubbox 之间的区别?
Dubbo 和 Dubbox 本质上没有区别,名字得含义扩展了 Dubbo 而已,以下扩展出来得功能,也是选择 Dubbox 很重要得考察点。
- 支持 REST 风格远程调用(HTTP+JSON/XML);
- 支持基于 Kryo 和 FST 的 Java 高效序列化实现;
- 支持基于 Jasckson 和 JSON 序列化;
- 支持基于嵌入式 Tomcat 的 HTTP remoting 体系;
- 升级 spring 至 3.x;
- 升级 ZooKeeper 客户端;
- 支持完全基于 Java 代码的 Dubbo 配置;
注册中心
13.Dubbo 有哪些注册中心?
zookeeper(官方推荐)
优点:支持分布式;很多周边产品
缺点:受限于 Zookeeper 软件的稳定性;Zookeeper 专门辅助软件稳定较优
Multicast
优点:去中心化,不需要单独安装软件
缺点:Provider 和 Consumer 和 Registry 不能跨机房(路由)
Redis
优点:支持集群,性能高
缺点:要求服务器时间同步,否则可能会出现集群失败的问题
Simple
优点:标准 RPC 服务,没有兼容问题
缺点:不支持集群
14.Dubbo 的注册中心集群挂掉,发布者和订阅者之间还能通信么?
如果 dubbo 的注册中心集群挂掉,发布者和订阅者之间还能通信;启动 dubbo 时,消费者会从 zk 拉取注册的生产者的地址接口等数据,缓存本地。每次调用时,按照本地存储的地址进行调用
- 注册中心对等集群,任意一台宕掉后,会自动切换到另一台
- 注册中心全部宕掉,服务提供者和消费者仍可以通过本地缓存通讯
- 服务提供者无状态,任一台宕机后,不影响使用
- 服务提供者全部宕机,服务消费者会无法使用,并无限次重连等待服务者恢复。
集群
15.Dubbo 集群提供了哪些负载均衡策略?
1.Random LoadBalance(随机,按照权重的设置随机概率)
2.RoundRobinLoadBalance(轮询,按照权重设置轮询比率)
3.LeastActive LoadBalance(最少活跃数,响应快的提供者接受越多请求,响应慢的接受越少请求)
- ConsistentHashLoadBalance(一致性 Hash,相同参数的请求总是发到同一个服务提供者(相同参数默认是指请求的第一个参数)根据服务提供者 ip 设置 hash 环,携带相同的参数总是发送的同一个服务提供者,若服务挂了,则会基于虚拟节点平摊到其他提供者上
16.Dubbo 的集群容错方案有哪些?
failover cluster 模式
provider 宕机重试以后,请求会分到其他的 provider 上,默认两次,可以手动设置重试次数,建 议把写操作重试次数设置成 0。
failback 模式
失败自动恢复会在调用失败后,返回一个空结果给服务消费者。并通过定时任务对失败的调用进行 重试,适合执行消息通知等操作。
failfast cluster 模式
快速失败只会进行一次调用,失败后立即抛出异常。适用于幂等操作、写操作,类似于 failover cluster 模式中重试次数设置为 0 的情况。
failsafe cluster 模式
失败安全是指,当调用过程中出现异常时,仅会打印异常,而不会抛出异常。适用于写入审计日志 等操作。
forking cluster 模式
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多 服务资源。可通过 forks="2" 来设置最大并行数。
broadcacst cluster 模式
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志 等本地资源信息。
配置
17.Dubbo 配置文件是如何加载到 Spring 中的?
Spring 容器在启动的时候 ,会读取到 Spring 默认的 一 些 schema 以 及 Dubbo 自定 义 的 schema, 每 个 schema 都 会 对 应 一个自己的 NamespaceHandler,NamespaceHandler 里 面 通 BeanDefinitionParser 来解析配置信息并转化为需要加载的 bean 对象 !
18.说说核心的配置有哪些?
| 标签 | 用途 | 解释 |
|---|---|---|
| <dubbo:service/> | 服务配置 | 用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心 |
| <dubbo:reference/><sup>[2]</sup> | 引用配置 | 用于创建一个远程服务代理,一个引用可以指向多个注册中心 |
| <dubbo:protocol/> | 协议配置 | 用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受 |
| <dubbo:application/> | 应用配置 | 用于配置当前应用信息,不管该应用是提供者还是消费者 |
| <dubbo:module/> | 模块配置 | 用于配置当前模块信息,可选 |
| <dubbo:registry/> | 注册中心配置 | 用于配置连接注册中心相关信息 |
| <dubbo:monitor/> | 监控中心配置 | 用于配置连接监控中心相关信息,可选 |
| <dubbo:provider/> | 提供方配置 | 当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选 |
| <dubbo:consumer/> | 消费方配置 | 当 ReferenceConfig 某属性没有配置时,采用此缺省值,可选 |
| <dubbo:method/> | 方法配置 | 用于 ServiceConfig 和 ReferenceConfig 指定方法级的配置信息 |
| <dubbo:argument/> | 参数配置 | 用于指定方法参数配置 |
19.Dubbo 超时设置有哪些方式?
dubbo 超时时间设置有两种方式:
- 服务提供者端设置超时时间,在 Dubbo 的用户文档中,推荐如果能在服务端多配置就尽量多配置,因为服务提供者比消费者更清楚自己提供的服务特性。
- 服务消费者端设置超时时间,如果在消费者端设置了超时时间,以消费者端为主,即优先级更高。因为服务调用方设置超时时间控制性更灵活。如果消费方超时,服务端线程不会定制,会产生警告。
20.Dubbo 超时的原因及解决方案?
在分布式系统中,超时是一个常见的问题。Dubbo 作为一款高性能的 RPC 框架,也难免会遇到超时问题。超时可能由多种原因引起,以下是一些常见的原因:
- 网络延迟:网络延迟可能导致请求在传输过程中花费过长的时间,从而导致超时。
- 服务端处理时间过长:服务端的处理时间过长,无法在规定的时间内完成响应,也会导致超时。
- 系统资源不足:当系统资源(如 CPU、内存、线程等)不足时,可能会影响请求的处理速度,从而导致超时。
- 序列化问题:Dubbo 默认使用 Hessian 进行序列化,如果服务端和客户端的序列化不一致,可能会导致超时。
针对以上问题,以下是一些可能的解决方案: - 优化网络环境:尽量减少网络延迟,可以通过优化网络配置、使用更快的网络连接等方式实现。
- 优化服务端性能:对服务端进行性能优化,如优化代码、使用缓存、升级硬件等。同时,也可以通过监控工具对服务端性能进行实时监控,以便及时发现并解决问题。
- 调整超时时间:根据实际情况调整超时时间,以满足系统的需求。如果系统对响应时间要求较高,可以适当缩短超时时间;反之,可以适当延长超时时间。
- 使用合适的序列化方式:根据实际情况选择合适的序列化方式,以保证服务端和客户端的序列化一致性。例如,可以考虑使用 FastJson 等其他序列化方式。
- 排查 GC 问题:如果超时问题与 GC 有关,可以通过查看 GC 日志、分析 GC 情况等方式排查问题。同时,也可以考虑调整 JVM 参数,如堆大小、GC 方式等,以提高系统性能。
- 检查服务端负载:如果服务端负载过高,可能会导致超时问题。可以通过监控工具检查服务端的负载情况,并根据实际情况进行调整。例如,可以通过增加服务器数量、优化服务端代码等方式减轻服务端负载。
- 调整线程池大小:如果系统线程池大小不合适,可能会导致请求处理速度过慢,从而引发超时问题。可以根据实际情况调整线程池大小,以满足系统的需求。
- 使用异步调用:对于一些不需要立即得到结果的操作,可以考虑使用异步调用来提高系统性能。异步调用可以在不阻塞主线程的情况下执行一些耗时的操作,从而提高系统的并发处理能力。
- 增加重试机制:对于一些可能因为暂时性原因导致超时的请求,可以在客户端增加重试机制,以提高系统的可用性和稳定性。当然,重试机制的设计也需要谨慎考虑,避免不必要的重试导致的问题。
- 排查第三方依赖:如果系统使用了第三方库或依赖,可能会导致超时问题。可以通过排查第三方依赖的方式解决问题,例如升级第三方库版本、替换其他第三方库等。
以上是一些常见的 Dubbo 超时原因及解决方案。在实际应用中,需要根据具体情况进行分析和排查。同时,也需要保持对系统的持续监控和维护,及时发现并解决问题,以确保系统的稳定性和可用性。
通信协议
21.Dubbo 使用的是什么通信框架?
默认使用 NIO Netty 框架
22.Dubbo 支持哪些协议,它们的优缺点有哪些?
dubbo 协议 (官方推荐):适合大并发小数据量的服务调用,以及消费者远大于提供者。传输协议为 TCP,支持异步通信和 Hessian 序列化。
应用场景:适用于大并发小数据量的服务调用,以及消费者远大于提供者的场景。
优点:支持异步通信,性能较高。
缺点:只能在 Java 环境下使用。
rmi 协议:采用 JDK 标准的 RMI 协议,适用于 Java 环境下的服务调用。
应用场景:适用于 Java 环境下的服务调用。
优点:使用 JDK 标准的 RMI 协议,易于使用。
缺点:只能在 Java 环境下使用。
hessian 协议:采用 Hessian 二进制序列化协议,适用于 Java 环境下的服务调用。
应用场景:适用于 Java 环境下的服务调用。
优点:采用二进制序列化,传输效率高。
缺点:只能在 Java 环境下使用。
http 协议:采用 HTTP 传输协议,适用于各种语言环境下的服务调用。
应用场景:适用于各种语言环境下的服务调用。
优点:支持跨语言调用,使用方便。
缺点:传输效率相对较低。
webservice 协议:采用 SOAP 协议,适用于各种语言环境下的服务调用。
应用场景:适用于各种语言环境下的服务调用。
优点:采用 SOAP 协议,支持跨语言调用。
缺点:传输效率相对较低。
gRPC 协议:gRPC 是谷歌开源的基于 HTTP/2 的通信协议,支持多种编程语言,包括 C++,Java,Python,Go 等
应用场景:适用于各种语言环境下的服务调用。
优点:使用 HTTP/2 协议,显著降低带宽消耗和提高性能。
缺点:尚未提供连接池,基于 HTTP2,绝大部多数 HTTP Server、Nginx 都尚不支持。
设计模式
23.Dubbo 用到哪些设计模式?
Dubbo 框架在初始化和通信过程中使用了多种设计模式,可灵活控制类加载、权限控制等功能。
- 工厂模式
Provider 在 export 服务时,会调用 ServiceConfig 的 export 方法。ServiceConfig 中有个字段 :
java
private static final Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();Dubbo 里有很多这种代码。这也是一种工厂模式,只是实现类的获取采用了 JDK SPI 的机制。这么实现的优点是可扩展性强,想要扩展实现,只需要在 classpath 下增加个文件就可以了,代码零侵入。另外,像上面的 Adaptive 实现,可以做到调用时动态决定调用哪个实现,但是由于这种实现采用了动态代理,会造成代码调试比较麻烦,需要分析出实际调用的实现类。
- 装饰器模式
- 观察者模式
Dubbo 的 Provider 启动时,需要与注册中心交互,先注册自己的服务,再订阅自己的服务,订阅时,采用了观察者模式,开启一个 listener。注册中心会每 5 秒定时检查是否有服务更新,如果有更新,向该服务的提供者发送一个 notify 消息,provider 接受到 notify 消息后,运行 NotifyListener 的 notify 方法,执行监听器方法。
- 动态代理模式
Dubbo 扩展 JDK SPI 的类 ExtensionLoader 的 Adaptive 实现是典型的动态代理实现。Dubbo 需要灵活地控制实现类,即在调用阶段动态地根据参数决定调用哪个实现类,所以采用先生成代理类的方法,能够做到灵活的调用。生成代理类的代码是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法。代理类主要逻辑是,获取 URL 参数中指定参数的值作为获取实现类的 key。
运维管理
24.服务上线怎么兼容旧版本?
可以用 版本号( version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。
25.Dubbo telnet 命令能做什么?
dubbo 服务发布之后 , 我们可以利用 telnet 命令 **进行调试 、管理 **。
Dubbo2.0.5 以上版本服务提供端口支持 telnet 命令
- 连接服务:telnet localhost 20880//键 入回车进入 Dubbo 命令模式 。
- 查看服务列表
dubbo>ls
- 查看服务中的接口
dubbo>ls interfacd(接口名称)
- 显示服务列表
ls -l
- 调用服务接口
invoke XxxService.xxxMethod(“参数”)
26.Dubbo 支持服务降级吗?
支持服务降级;以通过 dubbo:reference 中设置 mock="return null"。 mock 的值也可以修改为 true,然后再跟接口同一个路径下实现一个 Mock 类,命名规则是“ 接口名称 +Mock”后缀 。然后在 Mock 类里实现自己的降级逻辑。
服务降级概述
1.服务器降级概述
服务器降级是一种在分布式系统中应对高流量和故障挑战的策略。它是一种牺牲某些功能或质量来保持系统基本功能可用性的方法。在分布式系统中,面临高并发请求、资源瓶颈或故障时,服务可能无法正常运行,这是服务降级可以帮助系统继续提供基本的核心功能,避免全崩溃。从而保障用户体验。
2.为什么需要服务降级
需要服务降级得主要原因包括以下几点:
- 高流量和突发流量:当系统面临高流量或突发流量时,原本正常运行的服务可能无法满足所有请求,导致性能下降甚至宕机。服务降级可以减轻服务的负担,确保核心功能的可用性。
- 资源限制:在分布式系统中,资源如数据库连接、内存、带宽等都是有限的。当资源达到极限时,服务降级可以通过减少不必要的操作或关闭某些功能来释放资源,以确保核心功能继续运行。
- 故障容忍:服务降级可以帮助系统在面临部分故障或异常情况下继续提供核心服务,而不至于因为一个组件的故障而导致整个系统不可用。
3.服务降级原理
服务降级的工作原理通常涉及以下几个方面:
- 监测与度量:系统需要监测关键指标,如请求响应时间、错误率、资源使用率等。这些度量数据可以用来判断系统是否需要降级。
- 降级策略:预定义一套降级策略,根据监测数据来决定何时以及如何降级。例如,可以设定响应时间超过阈值时触发降级,然后关闭某些不必要的功能或返回缓存数据。
- 降级动作:一旦触发了降级策略,系统会执行相应的降级动作,这可能包括停用某些模块、返回错误码、返回缓存数据等。
- 监测与恢复: 在服务降级后,系统仍然需要持续监测状态,一旦恢复正常,需要及时恢复被降级的功能。
服务降级是分布式系统中的一项重要策略,可以帮助系统在高流量和故障情况下保持稳定。然而,降级策略的设计和实施需要谨慎,需要确保核心功能的可用性,同时不过度降低用户体验。
服务降级配置
Dubbo 提供了服务降级的配置选项,允许开发人员定义降级策略,以应对高流量或故障情况。以下是 Dubbo 中的一些降级策略选项和配置示例:
1.降级策略选项
Dubbo 的降级策略选项通常在服务提供者端配置,以决定在哪些情况下执行服务降级。以下是一些常见的选项:
- mock:指定降级时调用的本地伪装(mock)实现,通常是一个本地的虚拟服务,用于返回默认值或预先定义的数据。
- mock 属性还可以设置为 force,表示无论远程调用是否成功,都会执行伪装操作。
- mock 属性还可以设置为 fail,表示无论远程调用是否成功,都会抛出异常。
服务降级最佳实践
服务降级的最佳实践包括流量控制和故障处理,以确保系统在高流量和故障情况下能够稳定运行:
1.流量控制:
- 限制并发请求:使用限流策略,例如令牌桶算法或漏桶算法,来限制服务的并发请求数量。这可以减轻系统负载,防止过多的请求导致服务崩溃。
- 服务降级预警:实施监控和告警机制,当系统流量达到预定的阈值时,及时发出警报,以便运维人员采取措施。
- 服务熔断:使用熔断器模式,例如 Hystrix,来监测服务的响应时间和错误率。当服务出现问题时,可以暂时关闭服务,防止不断的请求加重负载,等待服务恢复正常再重新开启。
2.故障处理:
- 优雅降级:在服务降级时,要考虑返回合理的响应,可以是默认数据、缓存数据或友好的错误提示,而不是简单地返回错误。这有助于提供更好的用户体验。
- 降级策略设计:降级策略应该根据业务需求来设计,选择哪些功能是可以被降级的,以及在降级时如何处理这些功能。需要在策略中平衡可用性和性能。
- 监控和日志记录:在降级时应该记录监控数据和错误日志,以便后续的问题排查和分析。这有助于了解降级的原因和影响。
3. 性能测试:
在实际部署之前,进行性能测试和负载测试是非常重要的。通过模拟高流量和故障情况,可以评估系统的表现,以确保服务降级策略能够有效地应对各种情况。
4. 自动化:
尽可能自动化服务降级策略的触发和恢复。自动化可以在发生问题时更快地响应,减少人工干预的需求。
5. 持续改进:
服务降级策略应该是一个持续改进的过程。定期审查和更新降级策略,根据实际运行情况来做出调整,以适应不断变化的系统需求和负载。
综上所述,服务降级的最佳实践包括流量控制和故障处理,需要谨慎设计降级策略,监控系统的表现,并进行性能测试以确保系统在高流量和故障情况下能够稳定运行。同时,自动化和持续改进也是确保服务降级策略有效性的关键因素。
27.Dubbo 如何优雅停机?
Dubbo_是通过 JDK 的 ShutdownHook 来完成优雅停机_ 的,所以如果使用 kill -9 PID 等强制关闭指令,是不会执行优雅 停机的,只有通过 kill PID 时,才会执行。
SPI
28.Dubbo SPI 和 Java SPI 区别?
- JDK SPI
JDK 标准的 SPI 会一次性加载所有的扩展实现,如果有的扩展很耗时,但也没用上,很浪费资源。所以只希望加载某个的实现,就不现实了
- Dubbo SPI
- 对 Dubbo 进行扩展,不需要改动 Dubbo 的源码
- 延迟加载,可以一次只加载自己想要加载的扩展实现。
- 增加了对扩展点 IOC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点。
- Dubbo 的扩展机制能很好的支持第三方 IoC 容器,默认支持 Spring Bean。
其他
29.Dubbo 支持分布式事务吗?
目前暂时 不支持,可与 通过 tcc-transaction 框架实现;tcc-transaction 是开源的 TCC 补偿性分布式事务框架
TCC-Transaction 通过 Dubbo 隐式传参的功能,避免自己对业务代码的入侵。
30.Dubbo 可以对结果进行缓存吗?
可以,为了提高数据访问的速度。Dubbo 提供了声明式缓存,以减少用户加缓存的工作量
<dubbo:referencecache="true" />
其实比普通的配置文件就多了一个标签 cache="true"
31.Dubbo 必须依赖的包有哪些?
Dubbo_必须依赖 JDK_,其他为可选。
32.Dubbo 支持哪些序列化方式?
Dubbo 默认使用的序列化框架是 Hessian 2.0: Hessian 是一种基于二进制的序列化协议,它具有简单、高效的特点,适用于网络传输和存储数据。Hessian 在 Dubbo 中被广泛使用,因为它可以在不同的编程语言之间进行对象的序列化和反序列化。
还可以使用以下方式:
- java 默认序列化:Dubbo 也支持使用 Java 默认的序列化方式,即使用 java.io.Serializable 接口进行序列化和反序列化。然而,这种方式的效率相对较低,而且对对象的定义和结构比较敏感。
- JSON:Dubbo 也支持使用 JSON 进行序列化和反序列化。JSON 是一种常见的文本格式,易于理解和处理。Dubbo 使用了一些 JSON 库 (如 Jackson、Fastjson 等) 来实现对象和 JSON 之间的转换。
- Protobuf:Dubbo 还支持使用 Google 的 Protobuf(Protocol Buffers) 进行序列化和反序列化。Protobuf 是一种语言无关、平台无关、可扩展的序列化框架,它具有高效、紧凑的特点,并支持版本兼容性和跨语言互操作性
- Avro:Dubbo 还提供了对 Apache Avro 的支持。Avro 是一种基于架构的序列化框架,具有灵活的架构演化和动态类型的特点,适用于大规模数据的处理。
- Kryo:Dubbo 还支持使用 Kryo 进行序列化和反序列化。Kryo 是一个快速、高效的序列化库,特别适用于大规模数据的传输和存储。
33.Dubbo 在安全方面有哪些措施?
- Dubbo 通过 Token 令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。
- Dubbo 还提供服务黑白名单,来控制服务所允许的调用方。
34.服务调用是阻塞的吗?
默认是阻塞的,可以异步调用,没有返回值的可以这么做。Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。
35.服务提供者能实现失效踢出是什么原理?
Dubbo 服务提供者能实现失效踢出的原理主要基于心跳检测和注册中心的维护机制。以下是详细解释:
- 心跳检测机制:Dubbo 使用心跳检测来监控服务提供者的状态。这通常是通过在服务提供者和消费者之间建立长连接,并定时发送心跳包来实现的。心跳包中包含消费者的身份信息和相关参数。当服务提供者接收到心跳包后,会进行响应,表示其仍然存活。如果服务提供者因为某种原因(如宕机、网络问题或负载过高等)无法响应心跳包,Dubbo 会判断该服务提供者已失效。
- 注册中心:Dubbo 的注册中心扮演着重要的角色。它维护着服务提供者的列表以及服务消费者的列表。当服务提供者注册到注册中心时,注册中心会保存它们的信息,包括 IP 地址、端口等。同时,注册中心会定期检测服务提供者的可用状态。
- 失效踢出处理:当服务提供者被标记为失效时,注册中心会触发失效踢出操作。这意味着在服务消费者获取可用服务提供者列表时,失效的服务提供者将被从列表中剔除,不再参与服务调用。通过这种方式,Dubbo 能够确保消费者不会将请求发送到已失效的服务提供者上,从而提升系统的稳定性和可用性。
此外,Dubbo 还提供了多种容错策略,如 Failover(失败自动切换)和 Failfast(快速失败)等。这些策略在处理服务调用失败时提供了不同的行为模式,以满足不同场景的需求。
综上所述,Dubbo 通过心跳检测、注册中心的维护以及失效踢出处理,实现了对服务提供者状态的实时监控和动态管理,从而确保了分布式系统的稳定性和可用性。
36.同一个服务多个注册的情况下可以直连某一个服务吗?
可以点对点直连,修改配置即可,也可以通过 telnet 直接某个服务。
37.Dubbo 服务降级,失败重试怎么做?
可以通过 dubbo:reference 中设置 mock="return null"。mock 的值也可以修改为 true,然后再跟接口同一个路径下实现一个 Mock 类,命名规则是“ 接口名称 +Mock”后缀。然后在 Mock 类里实现自己的降级逻辑
38.Dubbo 使用过程中都遇到了些什么问题?
在注册中心找不到对应的服务,检查 service 实现类是否添加了 @service 注解无法连接到注册中心,检查配置文件中的对应的测试 ip 是否正确
RPC
39.为什么要有 RPC
http 接口是在接口不多、系统与系统交互较少的情况下,解决信息孤岛初期常使用的一种通信手段;优点就是简单、直接、开发方便。利用现成的 http 协议进行传输。但是如果是一个大型的网站,内部子系统较多、接口非常多的情况下,RPC 框架的好处就显示出来了,首先就是长链接,不必每次通信都要像 http 一样去 3 次握手什么的,减少了网络开销;其次就是 RPC 框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。第三个来说就是安全性。最后就是最近流行的服务化架构、服务化治理,RPC 框架是一个强力的支撑。
socket 只是一个简单的网络通信方式,只是创建通信双方的通信通道,而要实现 rpc 的功能,还需要对其进行封装,以实现更多的功能。
RPC 一般配合 netty 框架、spring 自定义注解来编写轻量级框架,其实 netty 内部是封装了 socket 的,较新的 jdk 的 IO 一般是 NIO,即非阻塞 IO,在高并发网站中,RPC 的优势会很明显
40.什么是 RPC
RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。简言之,RPC 使得程序能够像访问本地系统资源一样,去访问远端系统资源。比较关键的一些方面包括:通讯协议、序列化、资源(接口)描述、服务框架、性能、语言支持等。

简单的说,RPC 就是从一台机器 (客户端) 上通过参数传递的方式调用另一台机器 (服务器) 上的一个函数或方法 (可以统称为服务) 并得到返回的结果。
41.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 步完好地封装起来,也就是把调用、编码/解码的过程给封装起来,让用户感觉上像调用本地服务一样的调用远程服务。
42.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 有何区别呢?
没什么太大区别,他们的本质都是提供可支持分布式的基础服务,最大的区别在于他们各自的的特点所带来的不同应用场景 。
43.RPC 框架需要解决的问题?
1、如何确定客户端和服务端之间的通信协议?
2、如何更高效地进行网络通信?