一、Dubbo中ZK集群挂掉,发布者和订阅者还能通信吗?
可以通信。
因为当启动Dubbo容器时,消费者会去注册中心拉取注册的提供者地址列表,并将其缓存到本地。每次发起调用时,都会按照本地的地址列表,以负载均衡的策略去进行调用。但是注册中心挂掉,则后续新的提供者无法被消费者发现。
- 注册中心对等集群,任意一台宕机后,会自动切换到另一台。
- 注册中心全部宕机,服务提供者和消费者仍然可以通过本地缓存通讯。
- 服务提供者无状态,任一台宕机后,不影响使用。
- 服务提供者全部宕机,服务消费者会无法使用,并无限次重连等待提供者恢复。
二、ZK实际如何存储Dubbo生产者和消费者信息?
- 如上图所示,ZK以树的形式存储生产者和消费者信息。
- 第一层,ROOT层,存放根节点。
- 第二层,接口层,存放接口的全限定名。
- 第三层,TYPE层,区分provider节点、Consumer节点。
- 第四层,URL层,存放服务的实例IP/PORT。
- monitor监控接口层及其子节点的情况,如果发生变化都会通知到monitor。
- Consumer的watcher机制监控TYPE层的provider节点。
- ZK中的节点都是临时节点。如果ZK通过心跳收不到实例的响应,则会把实例节点摘除。
- watcher机制监测到实例发生变化后,会通知到consumer。
三、Dubbo支持的注册中心有哪些?
- Zookeeper(官方推荐)
- 优点:支持分布式
- 缺点:受限于Zookeeper的特性。比如:ZK集群挂掉一半,整个集群可能就不可用了。ZK集群的节点选举问题。
- Multicast:组播协议允许将一台主机发送的数据通过网络路由器和交换机复制到多个加入此组播的主机,是一种一对多的通讯方式,每一台服务提供方和服务消费方都可以看作是注册中心的一部分。
- 优点:去中心化,不需要单独安装软件。
- 缺点:provider\consumer\registry不能跨机房(路由)。
不需要启动任何中心节点,只要广播地址一样,就可以互相发现,组播受网络结构限制,只适合小规模应用或者开发阶段使用。
- Redis
- 优点:支持集群,性能高。
- 缺点:要求服务器时间同步,否则可能出现集群失败问题。
- Simple
- 优点:标准RPC服务,没有兼容问题。
- 缺点:不支持集群。
四、Dubbo集群容错策略有哪些?
Consumer调用Provider某个实例失败后的处理方法就是容错策略。
- Failover Cluster: 失败自动切换。
Dubbo的默认容错方案。当调用失败时自动切换到其他可用的节点,具体的重试次数和间隔时间可通过引用服务的时候配置。默认重试次数为1。 - Failback Cluster: 失败自动恢复。在调用失败时记录日志和调用信息,然后返回空结果给Consumer,并且通过定时任务
每隔5秒对失败的调用进行重试。 - Failfast Cluster: 快速失败。只会调用一次,失败后立刻
抛出异常。 - Failsafe Cluster: 失败安全。调用出现异常,记录日志不抛出,返回空结果。
- Forking Cluster: 并行调用多个服务提供者。通过线程池创建多个线程,
并发调用多个provider,结果保存到阻塞队列中,只要有一个provider成功返回了结果,就会立刻返回结果。- 使用场景:对性能要求比较高的,并且provider接口是
幂等的。
- 使用场景:对性能要求比较高的,并且provider接口是
- Broadcast Cluster: 广播模式。
逐个调用provider,如果其中一台报错,在循环调用结束后,抛出异常。- 使用场景:对数据一致性要求比较高的。
五、Dubbo支持的协议有哪些?
-
Dubbo协议(官方推荐协议)
- 基于
TCP协议,使用socket通信。 - 采用
NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用)。 - 大文件上传时,可能出现问题(不使用Dubbo文件上传)。
- 基于
-
RMI(Remote Method Invocation)协议
- JDK自带的能力。可与原生RMI互操作,基于TCP协议,短连接。
-
Hessian协议
- Hessian是一种RPC框架,基于servlet进行通信。
- 可与原生Hessian互操作,
基于HTTP协议。Hessian的序列化机制会对文件进行压缩,所以对于数据包比较大的情况比较友好。 - 需要Hessian.jar支持,http短连接的开销大,它的参数和返回值都需要实现Serializable接口。
-
http协议。
-
Webservice: 基于CXF的Frontend-simple和Transports-http实现。基于webservice的远程调用协议。
- 序列化:SOAP文本序列化。
- 适用场景:系统集成,跨语言调用。
-
Thrift协议:Thrift是Facebook捐给Apache的一个RPC框架。
- 语言中立。
- 平台中立。
- 是个二进制的。
六、简述Dubbo的分层设计?
- service:业务层,就是咱们开发的业务逻辑层。
- Config:配置层,主要围绕ServiceConfig和ReferenceConfig,初始化配置信息。
- Proxy: 代理层,服务提供者和消费者都会生成一个代理类,使得服务接口透明化,代理层做远程调用和返回结果。
- Registry:注册层,封装了服务注册和发现。
- Cluster:路由和集群容错层,通过负载均衡选取具体调用的节点,处理特殊的调用要求和负责远程调用失败的容错措施。
- Monitor:监控层,负责监控统计调用时间和次数。
- Protocol:远程调用层,主要封装RPC调用,主要负责管理invoker。
- Exchange: 信息交换层。用来封装请求响应模型,同步转异步。
- Transport:网络传输层,抽象了网络传输的统一接口,Netty, Mina等。
- Serialize:序列换层。将数据序列化成二进制流,以及反序列化。
七、Dubbo和SpringCloud对比?
- Dubbo由于是二进制传输,占用宽带会更少。基于TCP协议,使用长连接,性能较好。
- SpringCloud是HTTP协议传输,占用宽带会比较多。而且是短连接,占用通信握手时间。同时使用HTTP协议一般会使用JSON报文,消耗会更大。
- Dubbo的开发难度较大,原因是Dubbo的jar包依赖问题很多大型工程无法解决。
- SpringCloud的接口协议约定比较自由且松散,需要强有力的行政措施来限制接口无序升级。
- Dubbo只是SpringCloud的一个子集,解决的是分布式中的服务调用问题,而SpringCloud提供了全套的解决方案。
- 服务调用方式:dubbo是RPC,SpringCloud是REST API。
七、Dubbo服务降级,失败重试怎么做?
- 可以通过<dubbo:reference>中设置mock="return null"。mock的值也可以修改为true。
- mock="force:return+null"。表示消费方对该服务的方法调用都直接返回null,不发起远程调用,用来屏蔽不重要服务不可用时对调用方的影响。
- mock="fail:return+null"。表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
- 在跟接口同一个路径下实现一个Mock类,命名规则是“接口名称+Mock”,在Mock类里实现自己的降级降级。
八、Dubbo如何优雅停机?
Dubbo是通过JDK的ShutdownHook来完成优雅停机的。
public class SpringExtensionFactory implements ExtensionFactory {public static void addApplicationContext(ApplicationContext context) {CONTEXTS.add(context);if (context instanceof ConfigurableApplicationContext) {((ConfigurableApplicationContext) context).registerShutdownHook();DubboShutdownHook.getDubboShutdownHook().unregister();}BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);}
- 担心两个钩子并发执行有问题?那就在可以注册 Spring 钩子的时候取消掉 JVM 的钩子。
- 担心当前 Spring 容器没有注册 Spring 钩子?那就显示调用 registerShutdownHook 进行注册。
九、Dubbo的序列化协议有哪些?
- Hessian2序列化,是Dubbo默认的序列化方式。
- Dubbo
- Fastjson
- Java自带序列化。