全部產品
Search
文件中心

Alibaba Cloud SDK:基於流控策略的優雅退避機制

更新時間:Jul 01, 2024

基於流控策略的優雅退避機制介紹。

說明

新增重試機制(重試機制)及流控策略。

核心庫 aliyun-java-sdk-core 從 4.6.0 版本開始支援重試機制(重試機制),以及提供基於流控策略的優雅退避方案。Maven 依賴如下:

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.6.0</version>
</dependency>
重要
  1. 並非所有產品 API 都支援基於流控策略的優雅退避機制,具體有哪些支援可參考各個產品介面文檔的流控資訊一欄,例如:ECS 的 DescribeHpcClusters 介面文檔:流控資訊

  2. 不管雲產品的介面是否支援流控退避策略,您都可在 SDK 中設定開啟流控退避機制,若介面不支援,則 SDK 的退避與靜默管控則不生效,與不開啟的狀態一致。但請注意,該方式存在風險,可能存在介面某一天突然開啟了流控退避的情況,導致您在調用中觸發流控突然導致靜默,增大排查難度。

  3. 請在開啟流控退避策略之後,依然保持對調用異常的監控,不能完全依賴於流控退避策略,以此導致漏查風險的狀況。

  4. 以下介紹,均是基於介面已支援流控退避的情況

基於流控策略的優雅退避機制

基於流控策略的優雅退避,簡單說分為兩種策略:

  • 重試退避策略

  • 流控靜默策略

重試機制中已講,重試時間間隔是根據指數退避來的,使用的 EqualJitter(指數退避)演算法計算出下次重試等待時間。除此之外,我們還提供了基於流控的優雅退避時間電腦制。

開啟流控控制

預設關閉流控策略的控制,若要開啟,則可使用以下兩種方式:

  1. 配置 RetryPolicy

RetryPolicy retryPolicy = RetryPolicy.builder()
                .maxNumberOfRetries(3) // 最大重試次數
                .maxDelayTimeMillis(20 * 1000) // 最大稍候再試時間,單位為毫秒,超過這個時間則不再重試
                //.retryConditions(retryConditions) // 觸發重試策略
                .enableAliyunThrottlingControl(true) // 使用阿里雲流控策略進行控制 
                //.throttlingConditions(throttlingConditions) // 限制重試策略
                .build();

request.setSysRetryPolicy(retryPolicy);
  1. 使用預設 RetryPolicy 策略

// 預設策略,入參為 enableAliyunThrottlingControl,true 表示開啟,false 表示關閉
RetryPolicy retryPolicy = RetryPolicy.defaultRetryPolicy( 
true 
);

request.setSysRetryPolicy(retryPolicy);

開啟流控控制的優勢

  1. 減少不必要的重試,降低系統消耗

  2. 更加準確利用退避時間,優雅地進行重試

高階

重試退避策略:基於流控策略下的退避時間計算

開啟流控策略的控制能力後,退避時間計算邏輯為:

  1. 如果沒有觸發流控,就一直用EqualJitter計算重試時間間隔;

  2. 如果觸發了流控,則取流控剩餘時間和 EqualJitter 計算結果的最大值做時間間隔,時間如果大於最大重試時間間隔的限制,則直接拋異常,並且將流控剩餘時間記錄在緩衝池中,以供流控靜默策略使用。

流控靜默策略

開啟流控策略的控制能力後,當觸發流控限制,服務端則會在返回頭(Header)中返迴流控剩餘的 quota 資訊,即針對【使用者】維度、【API + 使用者】維度,返回給用戶端以下資訊:API 呼叫剩餘次數、限流剩餘時間等。其中當被限流時,API 呼叫剩餘次數則為 0。

說明

兩個維度在 Header 中對應的 Key 值為:

  • 【API + 使用者】維度X-RateLimit-User-API

  • 【使用者】維度:X-RateLimit-User

針對【API + 使用者】維度舉例說明:

"X-RateLimit-User-API" : "Remain:1,Limit:2,Time:1000,TimeLeft:122,Reset:1637835220000"

Remain:剩餘量,int 類型,如果為 -1,則表示剩餘量足夠;如果已經被流控,則返回0;

Limit:流控的閾值上限,int 類型
Time:流控的時間跨度,long 類型,單位毫秒
TimeLeft:本流控周期剩餘時間,long 類型,單位毫秒
Reset:流控下一次周期開始時間,long 類型,毫秒時間戳記

而 SDK 會對流控剩餘時間進行管理,在這個時間段裡,若發起調用或者重試調用將會受到限制,如果這個時間大於最大稍候再試時間,則直接拋錯,若不大於最大間隔重試時間,則會靜默等待直到允許發起調用或重試。

開啟流控調試

在能力開啟的條件下,除了遇到流控限制的情況會返回 Header 中的流控剩餘的 quota 資訊外,還可以在正常調用時要求返回該 quota 資訊,只需要在要求標頭中加 X-RateLimit-Mode 欄位值為 debug 即可:

request.putHeadParameter("X-RateLimit-Mode", "debug");

這樣就會在每次介面調用的返回頭中拿到剩餘 quota 資訊。