「DUBBO系列」集群容錯策略Failover源碼分析

2020-09-05 科技萬物互聯

請點擊【關注】獲取更多網際網路和技術乾貨,頭條號IT徐胖子原創本文請勿轉載,感謝支持

1 文章概述

假設服務提供者提供A服務,但是A服務並不穩定,如果服務消費者無法正常消費A服務就需要做降級處理,不再消費A服務而是返回一個mock值,這就是所謂服務降級。

但是在降級之前,消費者有可能重試消費服務A,或者直接返回空結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文我們分析故障轉移策略。

Failover策略被稱為故障轉移策略,這是集群容錯默認策略。當第一次消費服務失敗後,消費者會根據Failover策略選擇其它生產者再次消費,默認重試次數是2次。

<beans> <dubbo:application name=&34; /> <dubbo:registry address=&34; /> <dubbo:reference id=&34; cluster=&34; retries=&34; interface=&34; /></beans>

public class Consumer { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { &34; }); context.start(); HelloService helloService = (HelloService) context.getBean(&34;); String result = helloService.sayHello(&34;); System.out.println(&34; + result); }}

// 通過動態代理機制生成代理對象Proxy// Proxy持有InvokerInvocationHandler// InvokerInvocationHandler持有invoker = MockClusterInvoker(FailoverClusterInvoker)HelloService helloService = (HelloService) context.getBean(&34;);

2 源碼分析

public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> { public FailoverClusterInvoker(Directory<T> directory) { super(directory); } @Override public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException { // 所有生產者invokers List<Invoker<T>> copyInvokers = invokers; checkInvokers(copyInvokers, invocation); String methodName = RpcUtils.getMethodName(invocation); // 獲取重試次數 int len = getUrl().getMethodParameter(methodName, Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES) + 1; if (len <= 0) { len = 1; } RpcException le = null; // 已經調用過的生產者 List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyInvokers.size()); Set<String> providers = new HashSet<String>(len); // 重試直到達到最大次數 for (int i = 0; i < len; i++) { if (i > 0) { // 如果當前實例被銷毀則拋出異常 checkWhetherDestroyed(); // 根據路由策略選出可用生產者Invokers copyInvokers = list(invocation); // 重新檢查 checkInvokers(copyInvokers, invocation); } // 負載均衡選擇一個生產者invoker Invoker<T> invoker = select(loadbalance, invocation, copyInvokers, invoked); invoked.add(invoker); RpcContext.getContext().setInvokers((List) invoked); try { // 服務消費發起遠程調用 Result result = invoker.invoke(invocation); if (le != null && logger.isWarnEnabled()) { logger.warn(&34; + methodName + &34; + getInterface().getName() + &34; + invoker.getUrl().getAddress() + &34; + providers + &34; + providers.size() + &34; + copyInvokers.size() + &34; + directory.getUrl().getAddress() + &34; + NetUtils.getLocalHost() + &34; + Version.getVersion() + &34; + le.getMessage(), le); } return result; } catch (RpcException e) { // 業務異常直接拋出 if (e.isBiz()) { throw e; } le = e; } catch (Throwable e) { le = new RpcException(e.getMessage(), e); } finally { providers.add(invoker.getUrl().getAddress()); } } throw new RpcException(le.getCode(), &34; + methodName + &34; + getInterface().getName() + &34; + len + &34; + providers + &34; + providers.size() + &34; + copyInvokers.size() + &34; + directory.getUrl().getAddress() + &34; + NetUtils.getLocalHost() + &34; + Version.getVersion() + &34; + le.getMessage(), le.getCause() != null ? le.getCause() : le); }}

3 文章總結

Failover策略是默認策略,所以我們在冪等設計時需要更加注意。例如服務生產者已經收到調用請求並已經處理成功,但是由於網絡原因返回結果時間被消費者認為超時,所以消費者會繼續重試調用,如果服務生產者沒有做好冪等就會出現重複處理問題,這個問題值得我們關注。

請點擊【關注】獲取更多網際網路和技術乾貨,頭條號IT徐胖子原創本文請勿轉載,感謝支持

相關焦點

  • 「DUBBO系列」集群容錯策略Failsafe源碼分析
    但是在降級之前,消費者有可能重試消費服務A,或者直接返回空結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文我們分析安全失敗策略。Failsafe策略被稱為安全失敗策略,只消費一次服務,如果消費失敗包裝一個空結果返回不拋出異常。我們來看一個消費者實例。
  • 「DUBBO系列」集群容錯策略Failfast源碼分析
    但是在降級之前消費者有可能重試消費服務A,或者直接返回錯誤結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文我們分析快速失敗策略。Failfast策略被稱為快速失敗策略,只消費一次服務,一旦消費失敗則拋出異常,我們看一個服務消費者代碼示例。
  • 「DUBBO系列」集群容錯策略Failback源碼分析
    但是在降級之前,消費者有可能重試消費服務A,或者直接返回空結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文分析失敗自動恢復策略。Failback策略被稱為失敗自動恢復策略,如果消費者服務消費失敗將返回一個空結果並記錄這次失敗請求,失敗請求會在另一個線程中進行異步重試,默認最大重試次數5次,如果重試超過5次還不成功則放棄重試並不拋出異常。
  • 集群容錯?看看Dubbo是如何實現的
    圖2:集群容錯實現類以Failsafe容錯策略為例,具體的容錯的實現代碼是放在doInvoker,下面還有一個問題就是如何選擇容錯策略。說完了dubbo的集群容錯的實現邏輯,我們看看Dubbo給我們提供了哪些容錯的策略。
  • 「DUBBO系列」線程池策略實現原理與源碼分析
    請點擊【關注】獲取更多網際網路和技術乾貨,頭條號IT徐胖子原創本文請勿轉載,感謝支持1 文章概述本系列文章已經分析了DUBBO線程模型實現原理,本文簡單進行回顧。DUBBO提供了多種線程池策略,選擇線程池策略需要在配置文件指定threadpool屬性<dubbo:protocol name=&34; threadpool=&34; threads=&34; /><dubbo:protocol name=&34; threadpool=&34; threads=&34; /><dubbo:protocol
  • 「DUBBO系列」服務降級源碼分析
    我們通過分析源碼講解服務降級策略,首先看一個消費者代碼實例。2.1 不配置降級策略<dubbo:reference id=&34; interface=&34; />2.2 強制降級策略<dubbo:reference id
  • 突破Java面試- Dubbo負載均衡及動態代理的策略
    1 面試題Dubbo負載均衡策略和集群容錯策略都有哪些?動態代理策略呢?2 考點分析這些都是關於Dubbo必須知道,基本原理,序列化是什麼協議,具體用dubbo的時候,如何負載均衡,如何高可用,如何動態代理等.
  • 「DUBBO系列」服務超時機制源碼分析
    1 文章概述DUBBO有很多地方可以配置超時時間,可以配置在消費者,可以配置在生產者,可以配置為方法級別,可以配置為接口級別,還可以配置為全局級別,DUBBO官方文檔介紹這些配置優先級如下:第一優先級:方法級 > 接口級 > 全局級第二優先級:消費者 > 生產者本文從源碼層面對超時機制進行分析
  • 「DUBBO系列」並發控制實現原理與源碼分析
    本文我們介紹生產者和消費者並發控制怎樣配置並且在源碼層面分析並發控制實現原理。:protocol name=&34; port=&34; /> <dubbo:service executes=&34; interface=&34; ref=&34; /></beans>2.2 源碼分析ExecuteLimitFilter過濾器是生產者並發控制核心
  • Dubbo-go 源碼筆記(二)客戶端調用過程
    接下來,就要通過閱讀源碼,看看 dubbo-go 是如何做到的。實現遠程過程調用1.{ return &failoverClusterInvoker{ baseClusterInvoker: newBaseClusterInvoker(directory), }}12345dubbo-go 框架默認選擇 failover 策略,既然返回了一個 invoker,我們查看一下 failoverClusterInvoker 的 Invoker 方法
  • 「DUBBO系列」鏈路跟蹤實現原理與源碼分析
    1.1 消費者配置<beans> <dubbo:registry address=&34; /> <dubbo:reference id=&34; interface=&34; /><beans>
  • 「DUBBO系列」線程模型實現原理與源碼分析
    :protocol name=&34; dispatcher=&34; /><dubbo:protocol name=&34; dispatcher=&34; /><dubbo:protocol name=&34; dispatcher=&34; /><dubbo:protocol name=&34; dispatcher=&34; /><dubbo:
  • 俯瞰Dubbo全局,閱讀源碼前必須掌握這些!!
    為使更多童鞋受益,現給出開源框架地址:https://github.com/sunshinelyz/mykit-delay既然是要寫深度解析Dubbo源碼的系列專題,我們首先要做的就是搭建一套Dubbo的源碼環境,正所謂「工欲善其事,必先利其器」。
  • 大廠面試系列(五):Dubbo和Spring Cloud
    Dubbo和Spring Cloud相關Dubbo你說你了解dubbo,能講一下dubbo的基本原理嗎? dubbo支持的通信協議和序列化協議? dubbo負載均衡和集群容錯策略有哪些?dubbo複製均衡策略和高可用策略都有哪些啊?動態代理策略呢?Dubbo服務調用的概述 consumer每次都要去拉註冊中心provider的信息嗎 consumer會緩存所有的provider元信息嗎為什麼要進行系統拆分啊?拆分不用dubbo可以嗎?dubbo和thrift什麼區別啊?
  • Spring全家桶、Dubbo、分布式、消息隊列後端必備全套開源項目
    整合 Sentinel」小節Hystrix《Spring Boot 服務容錯 Hystrix 入門》的「6.集成到 Dubbo」小節《Spring Cloud Netflix 服務容錯 Hystrix 入門》的「10.
  • 「Java崗」5年經驗,7面阿里,「過五關斬六將」拿下P7
    volatile從指令重排序,內存屏障資料庫,MySQL索引,執行計劃、count1*區別、舉例優化sql、MVCC和事務隔離級別的關係、間隙鎖、行鎖JVM調優(可達性分析算法中根節點有哪些、cms和G1區別、怎樣GC調優、怎樣排查CPU彪高、內存彪高、逃逸分析)redis數據結構、跳躍表、redis qps能上多少,怎麼知道的
  • 「DUBBO系列」線程池打滿問題分析方法與實例
    運行程序發現生產者和消費者都拋出異常信息,下面我們從三個維度分析這個問題。通過分析消費者日誌我們知道生產者線程池被打滿,而且可以定位到哪一個方法報錯。消費者需要做好降級策略,例如使用mock機制或者熔斷保護系統。我們還可以查找生產者地址在控制臺查詢這臺機器服務運行情況,如果不是本團隊維護還要聯繫相關技術團隊迅速處理。2.3 生產者分析通過分析生產者日誌我們知道生產者線程池被打滿,但是不知道哪一個方法報錯,這就需要結合線程快照進行分析。
  • 我終於知道什麼是Dubbo了
    之前有人問我,你用過dubbo嗎?嗯,額,我說,沒了解過。那你知道SpringCloud嗎?嗯,額,我說,我聽說過,好像是微服務用到的一種技術框架。哎,為了下次有人跟我聊起dubbo,我能不再像便秘一樣,嗯……額……於是,我決定學習dubbo!
  • 原理+應用+集群+拓展+源碼五飛
    這份手冊分為分為基礎和應用篇、原理篇、集群篇、拓展篇、源碼篇共 5 大塊內容。基礎和應用篇講解對讀者來說有價值的內容,可以直接應用到實際工作中;原理篇、集群篇讓開發者透過簡單的技術表面看到精緻的底層世界;拓展篇幫助讀者拓展技術視野和夯實基礎,便於進階學習;源碼篇讓高階的讀者能夠讀懂源碼,掌握核心技術!
  • 用隧道協議實現不同dubbo集群間的透明通信
    class TunnelInterfaceResp{ // dubbo元信息 MetaData dubbo // 返回值調用序列化後的比特流,由另一個集群的對應系統返回 byte[] resp;}有了這個dubbo接口,我們就可以很容易的將數據傳送給默認網關了。