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
- Type
- Service
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 代理。