集群容錯?看看Dubbo是如何實現的

2020-10-16 JAVA吳彥祖

大家好,我是java吳彥祖!

隨著網際網路的發展,傳統垂直架構已經無法應對滿足網際網路企業經常面對的高並發、集群和大數據量等特點,所以這就是Dubbo誕生的目的,本文會以最簡單的方式給大家講述Dubbo中集群容錯實現邏輯以及使用場景。

圖1:集群容錯流程

Dubbo集群容錯實現邏輯

在分布式項目中為了做到服務的高可用,我們往往需要服務集群化。如果集群服務中出現了某個服務故障則就需要集群實現容錯機制。

容錯的實現是在Dubbo的容錯層中,具體還是要先看AbstractClusterInvoker這個抽象類,它定義了最基本的整個集群容錯層的流程模版。

通過AbstractClusterInvoker我大致可以看到整個集群容錯層的調用流程是這樣的:

1.調用AbstractClusterInvoker#invoke(final Invocation invocation);初始化LoadBalance和Invoker列表2.調用AbstractClusterInvoker#doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance);3.doInvoker方法的具體實現是在各個實現類中的如下圖2所示;4.實現類中會調用調用AbstractClusterInvoker(父類)中的select方法做負載均衡策略;

圖2:集群容錯實現類

以Failsafe容錯策略為例,具體的容錯的實現代碼是放在doInvoker方法中。

public class FailsafeClusterInvoker<T> extends AbstractClusterInvoker<T> { private static final Logger logger = LoggerFactory.getLogger(FailsafeClusterInvoker.class); public FailsafeClusterInvoker(Directory<T> directory) { super(directory); } // 實現 public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException { try { this.checkInvokers(invokers, invocation); Invoker<T> invoker = this.select(loadbalance, invocation, invokers, (List)null); return invoker.invoke(invocation); } catch (Throwable var5) { logger.error("Failsafe ignore exception: " + var5.getMessage(), var5); return AsyncRpcResult.newDefaultAsyncResult((Object)null, (Throwable)null, invocation); } }}

既然知道了容錯的實現流程和邏輯,下面還有一個問題就是如何選擇容錯策略。這個其實和負載均衡是一樣的,也是利用的Dubbo的SPI機制。實現的流出大致是這樣的:

1.集群容錯層中有一個Cluster接口,該接口我們可以看到被@SPI註解標註、方法上被@Adaptive註解標識(SPI機制後續會詳細說明);

// 默認用的是failover(故障轉移)@SPI("failover")public interface Cluster { @Adaptive <T> Invoker<T> join(Directory<T> directory) throws RpcException;}

2.我們點一下實現類AbstractCluster(抽象類)中有一個doJoin的方法,點一下實現類,發現自帶有八種實現類;

圖3:容錯實現類

3.隨便點一個實現類以上面的FailSafeCluster為例,我們可以看到具體的實現方式;

public class FailsafeCluster extends AbstractCluster { public static final String NAME = "failsafe"; public FailsafeCluster() { } public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException { return new FailsafeClusterInvoker(directory); }}

我們看到FailsafeCluster在創建時還會傳入一個Directory對象(List<Invoker>),Directory其實就是一組Invoker。

protected List<Invoker<T>> list(Invocation invocation) throws RpcException { return this.directory.list(invocation); }

4.最後SPI機制肯定是需要配置文件

圖4:Cluster SPI配置文件

Dubbo中自帶的集群容錯機制

說完了dubbo的集群容錯的實現邏輯,我們看看Dubbo給我們提供了哪些容錯的策略。

官網其實已經給我們說了有哪些集群容錯可以選擇(http://dubbo.apache.org/zh-cn/docs/user/demos/fault-tolerent-strategy.html)。我這邊主要是說一下幾種在工作中常用的集群容錯的策略。

  • Failover Cluster(失敗自動切換):失敗自動切換,當出現失敗,重試其它伺服器。通常用於讀操作,但重試會帶來更長延遲。可通過 retries="2" 來設置重試次數(不含第一次)。Failover Cluster其實一般使用在冪等的操作是比較合適的。
  • Failfast Cluster(快速失敗):只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。
  • Failsafe Cluster(失敗安全):出現異常時,直接忽略。通常用於寫入審計日誌等操作。一般用於可以缺失的非主流程,業務中用的不多;

其實的容錯策略直接去官網查看即可,現實業務中基本不可能使用(反正我是除了面試外,沒用到過)。

Dubbo中如何自定義集群容錯機制

在dubbo中如何進行自定義的集群容錯機制,其實和負載均衡流程是一樣的,畢竟都是基於Dubbo SPI擴展的。我這邊就直接基於Dubbo官網和大家說一下即可,畢竟這個擴展還是比較簡單的(http://dubbo.apache.org/zh-cn/docs/dev/impls/cluster.html)。

  • 擴展說明

當有多個服務提供方時,將多個服務提供方組織成一個集群,並偽裝成一個提供方。

  • 擴展接口

org.apache.dubbo.rpc.cluster.Cluster

  • 擴展配置

<dubbo:protocol cluster="xxx" /><!-- 預設值配置,如果<dubbo:protocol>沒有配置cluster時,使用此配置 --><dubbo:provider cluster="xxx" />

  • 已知擴展
  • org.apache.dubbo.rpc.cluster.support.FailoverCluster
  • org.apache.dubbo.rpc.cluster.support.FailfastCluster
  • org.apache.dubbo.rpc.cluster.support.FailsafeCluster
  • org.apache.dubbo.rpc.cluster.support.FailbackCluster
  • org.apache.dubbo.rpc.cluster.support.ForkingCluster
  • org.apache.dubbo.rpc.cluster.support.AvailableCluster
  • 擴展示例

Maven 項目結構:

src |-main |-java |-com |-xxx |-XxxCluster.java (實現Cluster接口) |-resources |-META-INF |-dubbo |-org.apache.dubbo.rpc.cluster.Cluster (純文本文件,內容為:xxx=com.xxx.XxxCluster)

XxxCluster.java:

package com.xxx; import org.apache.dubbo.rpc.cluster.Cluster;import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;import org.apache.dubbo.rpc.cluster.Directory;import org.apache.dubbo.rpc.cluster.LoadBalance;import org.apache.dubbo.rpc.Invoker;import org.apache.dubbo.rpc.Invocation;import org.apache.dubbo.rpc.Result;import org.apache.dubbo.rpc.RpcException; public class XxxCluster implements Cluster { public <T> Invoker<T> merge(Directory<T> directory) throws RpcException { return new AbstractClusterInvoker<T>(directory) { public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException { // ... } }; }}

META-INF/dubbo/org.apache.dubbo.rpc.cluster.Cluster:

xxx=com.xxx.XxxCluster

相關焦點

  • 「DUBBO系列」集群容錯策略Failsafe源碼分析
    但是在降級之前,消費者有可能重試消費服務A,或者直接返回空結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文我們分析安全失敗策略。Failsafe策略被稱為安全失敗策略,只消費一次服務,如果消費失敗包裝一個空結果返回不拋出異常。我們來看一個消費者實例。
  • 「DUBBO系列」集群容錯策略Failfast源碼分析
    但是在降級之前消費者有可能重試消費服務A,或者直接返回錯誤結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文我們分析快速失敗策略。Failfast策略被稱為快速失敗策略,只消費一次服務,一旦消費失敗則拋出異常,我們看一個服務消費者代碼示例。
  • 「DUBBO系列」集群容錯策略Failover源碼分析
    但是在降級之前,消費者有可能重試消費服務A,或者直接返回空結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文我們分析故障轉移策略。Failover策略被稱為故障轉移策略,這是集群容錯默認策略。當第一次消費服務失敗後,消費者會根據Failover策略選擇其它生產者再次消費,默認重試次數是2次。
  • 「DUBBO系列」集群容錯策略Failback源碼分析
    但是在降級之前,消費者有可能重試消費服務A,或者直接返回空結果,或者延時重試,這就是所謂集群容錯策略。集群容錯策略有很多,本文分析失敗自動恢復策略。Failback策略被稱為失敗自動恢復策略,如果消費者服務消費失敗將返回一個空結果並記錄這次失敗請求,失敗請求會在另一個線程中進行異步重試,默認最大重試次數5次,如果重試超過5次還不成功則放棄重試並不拋出異常。
  • 用隧道協議實現不同dubbo集群間的透明通信
    隧道實現那麼,這個隧道具體是如何實現,系統A又是如何知道需要本集群沒有對應的接口,需要通過http隧道調用到另一個集群的呢?這就引入了我們的隧道網關。如何發現這個網關為了充分利用dubbo接口的註冊發現機制,筆者將隧道網關也暴露為一個dubbo接口,其輸入和輸出分別如下所示:// 隧道網關接口請求體class TunnelInterfaceReq { // dubbo元信息,例如具體調用接口信息 MetaData dubbo // 原始請求A調用序列化後的比特流 byte[] body;}// 隧道網關接口返回體
  • 突破Java面試- Dubbo負載均衡及動態代理的策略
    1 面試題Dubbo負載均衡策略和集群容錯策略都有哪些?動態代理策略呢?2 考點分析這些都是關於Dubbo必須知道,基本原理,序列化是什麼協議,具體用dubbo的時候,如何負載均衡,如何高可用,如何動態代理等.
  • 大廠面試系列(五):Dubbo和Spring Cloud
    Dubbo和Spring Cloud相關Dubbo你說你了解dubbo,能講一下dubbo的基本原理嗎? dubbo支持的通信協議和序列化協議? dubbo負載均衡和集群容錯策略有哪些?集群中的角色有哪些?集群中最少需要幾臺?ZooKeeper常用命令zookeeper的核心是什麼?zk原理知道嗎?zk都可以幹什麼?Paxos算法知道嗎?說一下原理和實現? 在你的項目中spring是如何管理zookeeper的?看了zookeeper源碼,你的收穫是什麼?
  • 我終於知道什麼是Dubbo了
    這句話有5個點要掌握:分布式:即應用場景是系統拆分,A系統和B系統需要通訊的情況下,需要一個RPC框架;高性能:要支持集群、負載均衡及容錯機制;透明化:即遠程方法調用,就像調用本地方法一樣,只需簡單配置,沒有任何API侵入;自動註冊:默認使用
  • SpringCloud與Dubbo的比較
    Dubbo一、dubbo簡介Dubbo是阿里巴巴公司開源的一個高性能優秀的服務框架,使得應用可通過高性能的RPC實現服務的輸出和輸入功能,可以和Spring框架無縫集成。流動計算架構當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集群容量,提高集群利用率。此時,用於提高機器利用率的 資源調度和治理中心(SOA)是關鍵。
  • 還不懂Dubbo負載均衡?看完讓你秒殺面試官
    隨著網際網路的發展,傳統垂直架構已經無法應對滿足網際網路企業經常面對的高並發、集群和大數據量等特點,所以這就是Dubbo誕生的目的,本文會以最簡單的方式給大家講述Dubbo中負載均衡策略以及如何擴展。我們可以發現Dubbo中負載均衡策略是分在集群容錯(Cluster)層中。對於集群容錯層的解釋是這樣的:封裝多個提供者的路由及負載均衡,並橋接註冊中心,以Invoker為中心,擴展接口為Cluster、Directory、Router和LoadBalance。將多個服務提供方組合為一個服務提供方,實現對服務消費方來透明,只需要與一個服務提供方進行交互。
  • 想進大廠,先自問 Dubbo 普普通通 9 問能答出來嗎
    從大的範圍來說,dubbo分為三層,business業務邏輯層由我們自己來提供接口和實現還有一些配置信息,RPC層就是真正的RPC調用的核心層,封裝整個RPC的調用過程、負載均衡、集群容錯、代理,remoting則是對網絡傳輸協議和數據轉換的封裝。劃分到更細的層面,就是圖中的10層模式,整個分層依賴由上至下,除開business業務邏輯之外,其他的幾層都是SPI機制。
  • RPC 服務框架 Dubbo 將正式得到官方維護與支持
    近日,Dubbo 項目官網更新了一則公告:dubbo項目將正式得到官方維護與支持,我們期待這款優秀的開源項目在未來持續保持活力,引領開源服務框架  --Alibaba
  • 史上最強Dubbo面試25題答案詳解:核心組件+架構設計+服務治理等
    Cluster:服務框架,提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集群支持。Registry:服務註冊,基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。5.Dubbo的核心組件?6.Dubbo服務註冊與發現的流程?
  • 史上最全 40 道 Dubbo 面試題及答案,看完碾壓面試官
    配置 | 配置說明 ---|--- dubbo:service | 服務配置 dubbo:reference | 引用配置 dubbo:protocol | 協議配置 dubbo:application | 應用配置 dubbo:module | 模塊配置 dubbo:registry | 註冊中心配置 dubbo:monitor
  • Dubbo-go v1.5.1發布,Dubbo 的 Go實現
    Dubbo-go 團隊近期發布了 Dubbo-go v1.5.1,Dubbo-go 是 Apache Dubbo 項目的 Go 實現。根據團隊的介紹,雖然 v1.5.1 是 v1.5 的一個子版本,但相比於 v1.5.0, 社區還是投入了很大人力添加了如下重大改進。
  • SpringCloud微服務:基於Nacos組件,整合Dubbo框架
    伴隨業務發展,服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集群容量,提高集群利用率。此時,用於提高機器利用率的資源調度和治理中心(SOA)是關鍵。
  • dubbo如何處理業務異常,這個一定要知道哦!
    dubbo的源碼進行分析,如果Dubbo的 provider端 拋出異常(Throwable),則會被 provider端 的ExceptionFilter攔截到,執行以下invoke方法,裡面有個實現Listener類,重寫了onResponse。
  • 俯瞰Dubbo全局,閱讀源碼前必須掌握這些!!
    進行實現。其中,dubbo-remoting-api是整個dubbo-rpc模塊的核心抽象,其他模塊是對dubbo-remoting-api的實現。其中dubbo-registry-api是整個dubbo-registry的核心抽象,其他模塊是對dubbo-registry-api的具體實現。
  • 微服務系列之DubboRPC通信
    Apache Dubbo 是一款高性能、輕量級的開源 Java RPC 框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。  聚合工程    項目結構如下圖,簡單介紹一下:dubbo-api:服務接口dubbo-provider:依賴服務接口,具體的業務實現,服務提供者dubbo-coonsumer:依賴服務接口,遠程調用服務,服務消費者
  • SpringCloud微服務:基於Nacos組件,整合Dubbo框架
    伴隨業務發展,服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集群容量,提高集群利用率。此時,用於提高機器利用率的資源調度和治理中心(SOA)是關鍵。