dubbo集群容错机制

谁践踏了优雅 2024-04-18 11:38 147阅读 0赞

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 Failover 重试。

format_png

各节点关系:

  1. 这里的 Invoker Provider 的一个可调用 Service 的抽象,Invoker 封装了 Provider 地址及 Service 接口信息
  2. Directory 代表多个 Invoker,可以把它看成 List ,但与 List 不同的是,它的值可能是动态变化的,比如注册中心推送变更
  3. Cluster Directory 中的多个 Invoker 伪装成一个 Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个
  4. Router 负责从多个 Invoker 中按路由规则选出子集,比如读写分离,应用隔离等
  5. LoadBalance 负责从多个 Invoker 中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选

Dubbo中具体实现失败重试的是FailoverClusterInvoker类,这里我们看下具体实现,主要看下doInvoke代码:

复制代码

  1. public Result doInvoke(Invocation invocation,final List<Invoker<T>> invokers,LoadBalance loadbalance) throws RpcException{
  2. // (1) 所有服务提供者
  3. List<Invoker<T>> copyinvokers = invokers;
  4. checkInvokers(copyinvokers,invocation);
  5. // (2)获取重试次数
  6. int len = getUrl().getMethodParameter(invocation.getMethodName(),Constants.RETRIES_KEY,Constants.DEFAULT_RETRIES) + 1;
  7. if(len <= 0){
  8. len = 1;
  9. }
  10. // (3)使用循环,失败重试
  11. RpcException le = null; // last exception
  12. List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyinvokers.size());
  13. Set<String> providers = new HashSet<String>();
  14. for(int i=0;i<len;i++){
  15. // 重试时,进行重新选择,避免重试时invoker列表已发生变化
  16. // 注意:如果列表发生了变化,那么invoked判断会失效,因为invoker示例已经改变
  17. if(i > 0){
  18. // (3.1)
  19. checkWhetherDestroyed(); // 如果当前实例已经被销毁,则抛出异常
  20. // (3.2) 重新获取所有服务提供者
  21. copyinvokers = list(invocation);
  22. // (3.3) 重新检查一下
  23. checkInvokers(copyinvokers,invocation);
  24. }
  25. // (3.4) 选择负载均衡策略
  26. Invoker<T> invoker = select(loadbalance,invocation,copyinvokers,invoked);
  27. invoked.add(invoker);
  28. RpcContext.getContext().setInvokers((List)invoked);
  29. // (3.5) 具体发起远程调用
  30. try{
  31. Result result = invoker.invoke(invocation);
  32. if(le != null && logger.isWarnEnabled()){
  33. ...
  34. }
  35. return result;
  36. }catch(RpcException e){
  37. if(e.isBiz()){ // biz exception
  38. throw e;
  39. }
  40. le = e;
  41. }catch(Throwable e){
  42. le = new RpcException(e.getMessage(),e);
  43. }finally{
  44. providers.add(invoker.getUrl().getAddress());
  45. }
  46. }
  47. throw new RpcException("抛出异常...");
  48. }

复制代码

  • 如上代码(2)从url参数里面获取设置的重试次数,如果用户没有设置则取默认的值,默认是重试2,这里需要注意的是代码(2)是获取配置重试次数又+1了。这说明 总共调用次数=重试次数+1 (1是正常调用)。
  • 代码(3)循环重复试用,如果第一次调用成功则直接跳出循环返回,否则循环重试。第一次调用时不会走代码(3.1)(3.2)(3.3)。如果第一次调用出现异常,则会循环,这时候i=1,所以会执行代码(3.1)检查是否有线程调用了当前ReferenceConfig的destroy()方法,销毁了当前消费者。如果当前消费者实例已经被消费,那么重试就没有意义了,所以会抛出RpcException异常。
  • 如果当前消费者实例没被销毁,则执行代码(3.2)重新获取当前服务提供者列表,这是因为从第一次调开始到线程可能提供者列表已经变化了,获取列表后,然后执行(3.2)又一次进行了校验。校验通过则执行(3.4),根据负载均衡策略选择一个服务提供者,再次尝试调用。负载均衡策略的选择下节会讲解。

5 重试模式及其特点

Failover Cluster(默认)

当服务消费方调用服务提供者失败后自动切换到其他服务提供者服务器进行重试。这通常用于读操作或者具有幂等的写操作,需要注意的是重试会带来更长延迟。可通过 retries=”2” 来设置重试次数(不含第一次)。

接口级别配置重试次数方法 ,如上配置当服务消费方调用服务失败后,会再重试两次,也就是说最多会做三次调用,这里的配置对该接口的所有方法生效。当然你也可以针对某个方法配置重试次数如下:

  1. 失败自动切换,当出现失败,重试其它服务器 \[1\]。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。
  2. 重试次数配置如下:
  3. <dubbo:service retries="2" />

  1. <dubbo:reference retries="2" />
  2. <dubbo:reference>
  3. <dubbo:method name="findFoo" retries="2" />
  4. </dubbo:reference>

Failfast Cluster

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

Failsafe Cluster

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

Failback Cluster

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

Forking Cluster

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

Broadcast Cluster

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

6 集群模式配置

  1. 按照以下示例在服务提供方和消费方配置集群模式
  2. <dubbo:service cluster="failsafe" />

  1. <dubbo:reference cluster="failsafe" />

发表评论

表情:
评论列表 (有 0 条评论,147人围观)

还没有评论,来说两句吧...

相关阅读

    相关 dubbo容错

    为了避免单点故障,现在的应用通常至少会部署在两台服务器上。对于一些负载比较高的服务,会部署更多的服务器。这样, 在同一环境下的服务提供者数量会大于1。对于服务消费者来说,同一环

    相关 谈谈dubbo容错

    从继承图可以看出有以下几种策略: Failover Cluster(失败转移) 当调用提供者的服务器发生错误时,再试下一个服务器。 用于读操作。重试有延时。设置重试次数

    相关 Dubbo容错

    Dubbo官网:[dubbo 2.7  集群容错][dubbo 2.7_] 集群容错指的是,当消费者调用提供者集群时发生异常的处理方案 一、Dubbo内置的容错策略

    相关 Dubbo-容错

    当一个项目(应用或服务)放在多台服务器上时,怎么实现高可用,这就是集群容错。 \------------------------------------------

    相关 Dubbo——容错

    Cluster层概述 在微服务环境中,为了保证服务的高可用,很少会有单点服务出现,服务通常都是以集群的形式出现的。然而,被调用的远程服务并不是每时每刻都保持良好状况,当某