查看原文
其他

面试官:Dubbo如何保证高可用?

点击蓝字

关注我们


前言

Dubbo的一些自身特性确保了Dubbo的高可用,比如当注册中心宕机后,服务提供者和服务消费者仍能通过本地缓存通讯;注册中心对等集群,任意一台宕掉后,将自动切换到另一台;当有多台服务提供者提供服务时,Dubbo内置了几种负载均衡算法,并且服务提供者是无状态的,任意一台宕掉后,不影响使用;Dubbo提供了集群容错方案及服务降级策略来保证高可用。


1.本地缓存通讯及Dubbo直连

注册中心

这里模拟一下当所有服务注册中心宕机后,服务提供者和服务消费者是否能够正常通讯。

启动Zookeeper,然后分别启动server-proivder和server-consumer,启动好后关闭Zookeeper,这时候注册中心是宕机的状态:

访问http://localhost:8081/hello/mrbird看是否可以成功消费服务:

可以看到服务提供者和服务消费者通讯是正常的,因为注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表。

Dubbo直连

使用注册中心来维护服务可以降低后期维护和拓展的复杂度,降低耦合。不过Dubbo也提供了绕过注册中心的方法,即服务消费者不通过注册中心,而是直接取访问服务提供者来获取服务,这种方式也称为Dubbo直连。

我们在服务消费者的@Reference注解上直接指定服务提供者的地址,即可实现Dubbo直连:


1
2
@Reference(url = "http://127.0.0.1:8080")
private HelloService helloService;



2.负载均衡

在分布式系统中有多台的服务器作为提供者负责处理各种网络请求,当同时有多个请求同时过来时,需要将其均摊在各台服务器上,避免了某台服务器压力过大而某台服务器则闲置的问题。


dubbo提供了几种负载均衡策略:见上文->Dubbo的负载均衡详解


3.集群容错

在集群调用失败时,Dubbo提供了多种容错方案,默认为 failover重试。


Dubbo的集群容错模式:


Failover Cluster


失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。


可通过retries="2"来设置重试次数,(不含第一次)。


Failfast Cluster


快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。


Failsafe Cluster


失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。


Failback Cluster


失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。


Forking Cluster


并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过forks="2”来设置最大并行数。


Broadcast Cluster


广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。



4.服务降级

Dubbo默认支持两种降级策略:

  1. mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。

  2. 还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。

我们可以在Dubbo Admin控制台上来处理降级。

为了模拟错误情况,我们改造服务提供者实现的hello方法:

@Overridepublic String hello(String message) { System.out.println("调用 cc.mrbird.provider.service.HelloServiceImpl#hello"); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } return "hello," + message;}

方法中让线程阻塞了2秒。

接着改造服务消费者,在@Reference注解上配置超时时间:

@Reference(timeout = 1000)private HelloService helloService;

在不进行服务降级的情况下,访问http://localhost:8081/hello/mrbird将看抛出异常:

在Dubbo Admin消费者列表上的屏蔽按钮对应mock=force:return+null策略,即不调用服务,直接返回null,

点击屏蔽后,再次访问http://localhost:8081/hello/mrbird

服务提供者的控制台也没有任何调用日志:

而容错按钮则对应mock=fail:return+null机制。点击容错按钮,再次访问http://localhost:8081/hello/mrbird:

上述结果证明了在mock=fail:return+null策略下,消费方对该服务的方法调用在失败后,再返回 null 值(之所以会输出多次调用日志,是因为Dubbo的重试机制)。



参考:

https://www.cnblogs.com/kebibuluan/p/13596131.html

https://blog.csdn.net/wpc2018/article/details/

 THE END


推荐阅读  

Docker入门保姆级教程四之镜像

CompletableFuture的正确打开方式

SpringBoot2.x 整合ShardingSphere5.x实现分表

面试官:Redis和Mysql如何保证数据一致性

点赞+在看,关注公众号回复“666”领取福利

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存