Dubbo 有几种配置方式?

https://dubbo.apache.org/zh/docs/concepts/configuration/ 官方文档
按照编程方式可以分为四种方式:API配置、XML配置、Annotation配置、属性配置。
还有自定义bean实现配置。实际上所有的配置,都是有对应的类去实现和加载。

Dubbo 如何和 Spring Boot 进行集成?

官方提供提供了集成库 dubbo-spring-boot ,对应仓库为 https://github.com/apache/incubator-dubbo-spring-boot-project
http://static.iocoder.cn/images/Dubbo/2018_03_01/01.png

Dubbo 调用是同步的吗?

默认情况下,调用是同步的方式。
可以异步,Consumer、Provider均可异步

谈谈对 Dubbo 的异常处理机制?

dubbo的异常处理类是com.alibaba.dubbo.rpc.filter.ExceptionFilter 类

  • 如果provider实现了GenericService接口,直接抛出
  • 如果是checked异常,直接抛出
  • 在方法签名上有声明,直接抛出
  • 异常类和接口类在同一jar包里,直接抛出
  • 是JDK自带的异常,直接抛出
  • 是Dubbo本身的异常,直接抛出
  • 否则,包装成RuntimeException抛给客户端

Dubbo 如何做参数校验?

参数验证功能是基于 JSR303 实现的,用户只需标识 JSR303 标准的验证 annotation,并通过声明 filter 来实现验证。

  • 参数校验功能,通过参数校验过滤器 ValidationFilter 来实现。
  • ValidationFilter 在 Dubbo Provider 和 Consumer 都可生效。
    • 如果我们将校验注解写在 Service 接口的方法上,那么 Consumer 在本地就会校验。如果校验不通过,直接抛出校验失败的异常,不会发起 Dubbo 调用。
    • 如果我们将校验注解写在 Service 实现的方法上,那么 Consumer 在本地不会校验,而是由 Provider 校验。

Dubbo 可以对调用结果进行缓存吗?

Dubbo 通过 CacheFilter 过滤器,提供结果缓存的功能,且既可以适用于 Consumer 也可以适用于 Provider 。
通过结果缓存,用于加速热门数据的访问速度,Dubbo 提供声明式缓存,以减少用户加缓存的工作量。
Dubbo 目前提供三种实现:

  • lru :基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。
  • threadlocal :当前线程缓存,比如一个页面渲染,用到很多 portal,每个 portal 都要去查用户信息,通过线程缓存,可以减少这种多余访问。
  • jcache :与 JSR107 集成,可以桥接各种缓存实现。

注册中心挂了还可以通信吗?

可以,影响服务的上下线,不影响已上线的服务以及通信

Dubbo 在 Zookeeper 存储了哪些信息?

Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送
zookeeper:

  • Root
    • Service
      • Type
        • URL

Dubbo Provider 如何实现优雅停机?

Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果用户使用 kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才会执行。
因为大多数情况下,Dubbo 的声明周期是交给 Spring 进行管理,所以在最新的 Dubbo 版本中,增加了对 Spring 关闭事件的监听,从而关闭 Dubbo 服务。

服务提供方的优雅停机过程

  • 首先,从注册中心中取消注册自己,从而使消费者不要再拉取到它。
  • 然后,sleep 10 秒( 可配 ),等到服务消费,接收到注册中心通知到该服务提供者已经下线,加大了在不重试情况下优雅停机的成功率。😈 此处是个概率学,嘻嘻。
  • 之后,广播 READONLY 事件给所有 Consumer 们,告诉它们不要在调用我了!!!【很有趣的一个步骤】并且,如果此处注册中心挂掉的情况,依然能达到告诉 Consumer ,我要下线了的功能。
  • 再之后,sleep 10 毫秒,保证 Consumer 们,尽可能接收到该消息。
  • 再再之后,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其它机器。
  • 再再再之后,关闭心跳线程。
  • 最后,检测线程池中的线程是否正在运行,如果有,等待所有线程执行完成,除非超时,则强制关闭。
  • 最最后,关闭服务器。

服务消费方的优雅停机过程

  • 停止时,不再发起新的调用请求,所有新的调用在客户端即报错。
  • 然后,检测有没有请求的响应还没有返回,等待响应返回,除非超时,则强制关闭。

Dubbo Provider 异常关闭时,如何从注册中心下线?

Zookeeper上创建临时节点,在Provider异常关闭时,等待Zookeeper会话超时,临时节点会自动删除。
redis上是key/Map的形式,map的key是url,value是过期时间,为例保证实时性,不使用 Redis 的自动过期机制,而是通过监控中心。正常状态Consumer和Provider定期延长过期时间。异常关闭,会被监控中心删除掉节点并通知下线。

Dubbo Consumer 只能调用从注册中心获取的 Provider 么?

不是,Consumer 可以强制直连 Provider 。在配置直接指定ip和端口即可。
另外还可以只订阅,不让Provider发布,也是在配置中设置。

Dubbo 支持哪些通信协议?

  • dubbo:// 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
  • http:// 短连接同步传输,传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。
  • rmi:// RMI 协议采用 JDK 标准的 java.rmi.* 实现,采用阻塞式短连接和 JDK 标准序列化方式。
  • webservice://
  • hessian://
  • thrift://
  • memcached://
  • redis://
  • grpc:// 2.7.5版本开始支持grpc,计划使用http2
  • jsonrpc:// 正在孵化

什么是本地暴露和远程暴露,他们的区别?

远程暴露,比较好理解。我们看到的,都是远程暴露。每次 Consumer 调用 Provider 都是跨进程,需要进行网络通信。
本地暴露,本地调用使用了 injvm:// 协议,是一个伪协议,它不开启端口,不发起远程调用,只在 JVM 内直接关联,但执行 Dubbo 的 Filter 链。

Dubbo 使用什么通信框架?

通信框架:

  • Netty3
  • Netty4
  • Mina
  • Grizzly

那么 Dubbo 是如何做技术选型和实现的呢?Dubbo 在通信层拆分成了 API 层、实现层。项目结构如下:

  • API 层:
    • dubbo-remoting-api
  • 实现层:
    • dubbo-remoting-netty3
    • dubbo-remoting-netty4
    • dubbo-remoting-mina
    • dubbo-remoting-grizzly
      再配合上 Dubbo SPI 的机制,使用者可以自定义使用哪一种具体的实现。
      dubbo最新版,默认使用Netty4版本。

Dubbo 支持哪些序列化方式?

  • Hessian2 基于 Hessian 实现的序列化拓展。dubbo:// 协议的默认序列化方案。
    • Hessian 除了是 Web 服务,也提供了其序列化实现,因此 Dubbo 基于它实现了序列化拓展。
    • 另外,Dubbo 维护了自己的 hessian-lite ,对 Hessian 2 的 序列化 部分的精简、改进、BugFix。
  • Dubbo :Dubbo 自己实现的序列化拓展。
  • Kryo :基于 Kryo 实现的序列化拓展。
  • FST :基于 FST 实现的序列化拓展。
  • JSON :基于 Fastjson 实现的序列化拓展。
  • NativeJava :基于 Java 原生的序列化拓展。
  • CompactedJava :在 NativeJava 的基础上,实现了对 ClassDescriptor 的处理。
  • Protobuf:后续的吧,孵化中?

Dubbo 有哪些负载均衡策略?

  • Random LoadBalance 默认随机,可按权重
  • RoundRobin LoadBalance 轮询
  • LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
  • ConsistentHash LoadBalance 一致性 Hash,相同参数的请求总是发到同一提供者。

Dubbo 有哪些集群容错策略?

  • Failover Cluster 失败自动切换,当出现失败,重试其它服务器。retries=”2”设置重试次数,不包含第一次
  • Failfast Cluster 快速失败,只发起一次调用,失败立即报错。
  • Failsafe Cluster 失败安全,出现异常时,直接忽略。
  • Failback Cluster 失败自动恢复,后台记录失败请求,定时重发。
  • Forking Cluster 并行调用多个服务器,只要一个成功即返回。forks=”2” 来设置最大并行数。
  • roadcast Cluster 广播调用所有提供者,逐个调用,任意一台报错则报错。

Dubbo 有哪些动态代理策略?

动态代理:

  • Javassist
  • JDK 原生自带
  • CGLIB
  • ASM

Dubbo动态代理使用了 Javassist 和 JDK 两种方式。

  • 默认情况下,使用 Javassist 。性能原因
  • 可通过 SPI 机制,切换使用 JDK 的方式。

那么是不是 JDK 代理就没意义?
实际上,JDK 代理在 JDK 1.8 版本下,性能已经有很大的提升,并且无需引入三方工具的依赖,也是非常棒的选择。所以,Spring 和 Motan 在动态代理生成上,优先选择 JDK 代理。

Dubbo SPI 的设计思想是什么?