すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud SDK:再試行メカニズム

最終更新日:Jan 15, 2025

このトピックでは、Alibaba Cloud SDK V1.0 for Java の再試行メカニズムについて説明します。

説明

再試行メカニズムとスロットリングポリシーが追加されました。詳細については、「スロットリングポリシーに基づく高度なバックオフメカニズム」をご参照ください。

コアライブラリ aliyun-java-sdk-core V4.6.0 以降では、再試行メカニズムがサポートされており、スロットリングポリシーに基づく高度なバックオフスキームが提供されています。詳細については、「スロットリングポリシーに基づく高度なバックオフメカニズム」をご参照ください。次の Maven 依存関係を追加する必要があります。

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.6.0</version>
</dependency>

再試行メカニズム

再試行メカニズムの無効化

再試行メカニズムはデフォルトで無効になっています。次のいずれかの方法を使用して、再試行ポリシーを none に指定することで、再試行メカニズムを無効にすることができます。

// クライアントの再試行ポリシーを指定して、再試行メカニズムを無効にします。
client.setSysRetryPolicy(RetryPolicy.none());

// リクエストの再試行ポリシーを指定します。リクエストの再試行ポリシー設定は、クライアントの再試行ポリシー設定よりも優先されます。
request.setSysRetryPolicy(RetryPolicy.none());

再試行ポリシー

次の種類の再試行ポリシーがサポートされています。

  1. 例外を指定します。

  2. HTTP ステータスコードを指定します。

  3. HTTP レスポンスヘッダーを指定します。

3 つのタイプのポリシーは独立しています。指定した条件のいずれかが満たされると、再試行が実行されるか、再試行が実行されません。ポリシーを使用して、再試行をトリガーまたは制限できます。

次のサンプルコードは、再試行をトリガーまたは制限するためのポリシーを設定する方法を示しています。

  • 再試行をトリガーする条件のコレクションを作成します。

Set<RetryCondition> retryConditions = new HashSet<RetryCondition>();

// 条件の例
// 再試行をトリガーするステータスコードを指定します。次の例では、ステータスコード 500 または 501 が返されたときに再試行が実行されます。
Set<Integer> statusCodes = new HashSet<Integer>();
statusCodes.add(500); // http ステータスコード
statusCodes.add(501); // http ステータスコード
// 再試行をトリガーするために使用されるポリシーにステータスコード設定を追加します。
retryConditions.add(StatusCodeCondition.create(statusCodes));

// 再試行をトリガーする例外を指定します。次の例では、SocketTimeoutException または IOException がスローされたときに再試行が実行されます。
Set<Class<?  extends Exception>> exceptions = new HashSet<Class<?  extends Exception>>();
exceptions.add(SocketTimeoutException.class); // 例外
exceptions.add(IOException.class); // 例外
// 再試行をトリガーするために使用されるポリシーに例外設定を追加します。
retryConditions.add(ExceptionsCondition.create(exceptions));
  • 再試行を制限する条件のコレクションを作成します。

Set<RetryCondition> throttlingConditions = new HashSet<RetryCondition>();

// 条件の例
// 再試行を制限するステータスコードを指定します。次の例では、ステータスコード 429 が返されたときに再試行が禁止されます。
Set<Integer> code = new HashSet<Integer>();
code.add(429); // 再試行を制限する HTTP ステータスコードを指定します。この例では、ステータスコード 429 が返された場合、再試行は禁止されます。
// 再試行を制限するために使用されるポリシーにステータスコード設定を追加します。
throttlingConditions.add(StatusCodeCondition.create(code));
  • RetryPolicy に条件を追加します。

RetryPolicy retryPolicy = RetryPolicy.builder()
                .maxNumberOfRetries(3) // 最大再試行回数。
                .maxDelayTimeMillis(20 * 1000) // 最大再試行間隔。単位:ミリ秒。指定された時間を超えると、再試行は実行されません。
                .retryConditions(retryConditions) // 再試行をトリガーするために使用されるポリシー。
                . .throttlingConditions(throttlingConditions) // 再試行を制限するために使用されるポリシー。
                .build();

各再試行の間隔は、指数バックオフアルゴリズムを使用して計算されます。EqualJitter アルゴリズムは、次の再試行の待機時間を計算するために使用されます。

再試行の条件の高度な設定

3 つの条件が提供されています。以下の項目では、条件の詳細について説明します。

  1. StatusCodeCondition

    1. この条件は整数の集合を格納します。SDK は、コレクション内の HTTP ステータスコードを返されたステータスコードと比較し、再試行をトリガーするか制限するかを決定します。

  2. ExceptionsCondition

    1. この条件は例外の集合を格納します。SDK は、コレクション内の例外を呼び出しでスローされた例外と比較し、再試行をトリガーするか制限するかを決定します。

  3. HeadersCondition

    1. この条件はマップを格納します。マップの構造は複雑です。マップのキーはレスポンスヘッダーのキーと一致します。Pattern(com.aliyuncs.policy.retry.pattern.Pattern) インターフェースを呼び出して、マップの値を取得する必要があります。レスポンスヘッダーのキーに対応する値は、式によって照合されます。たとえば、値に文字列が含まれているか、値と等しいかがチェックされます。

    2. 2 つのパターンがサポートされています:AliyunThrottlingPattern と SimplePattern。AliyunThrottlingPattern パターインターフェースは、Alibaba Cloud によって提供されるスロットリングポリシーに基づいて呼び出されます。詳細については、「スロットリングポリシーに基づく高度なバックオフメカニズム」をご参照ください。SimplePattern パターインターフェースは、値が等しいかどうかを比較します。

    3. カスタムパターインターフェースを作成できます。パターインターフェースを含むクラスでは、次の関数を実装する必要があります。

      1. meetState(): 指定した条件が満たされているかどうかを指定します。

      2. escapeTime(): エスケープ時間を指定します。この関数は、再試行を制限するために使用されるポリシーにのみ適用されます。値が -1 でない場合、エスケープ時間中は再試行は実行されず、再試行は制限されません。代わりに、再試行が実行できるようになるまで再試行が実行されます。値が最大再試行間隔よりも大きい場合、システムはエラーメッセージを返し、再試行を待つ必要はありません。

      3. readFormHeadersContent(String content): パラメータに値を割り当てます。SimplePattern クラスの実装を直接使用できます。

  4. カスタム条件

    1. RetryCondition インターフェースのみを呼び出すことで、カスタム条件を作成できます。RetryCondition インターフェースを呼び出すには、次の 2 つのインターフェース関数を実装する必要があります。

      1. meetState(RetryPolicyContext var1): コンテキストに基づいて、一致ステータスが満たされているかどうかを判断します。

      2. escapeTime(RetryPolicyContext var1): エスケープ時間を計算します。この関数は、再試行を制限するために使用されるポリシーにのみ適用されます。関数を再試行をトリガーするために使用されるポリシーに適用する場合は、値を -1 に設定します。

完全なサンプルコード

サンプルコード:

package com.aliyun.sample;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.exceptions.ThrottlingException;
import com.aliyuncs.policy.retry.RetryPolicy;
import com.aliyuncs.policy.retry.conditions.ExceptionsCondition;
import com.aliyuncs.policy.retry.conditions.RetryCondition;
import com.aliyuncs.policy.retry.conditions.StatusCodeCondition;
import com.aliyuncs.profile.DefaultProfile;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashSet;
import java.util.Set;

public class Sample {
    public static void main(String[] args) {
        // DefaultAcsClient インスタンスを作成し、インスタンスを初期化します。
        DefaultProfile profile = DefaultProfile.getProfile(
                // リージョン ID。
                "cn-hangzhou",
                // 環境変数から Resource Access Management (RAM) ユーザーの AccessKey ID を取得します。
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                // 環境変数から RAM ユーザーの AccessKey Secret を取得します。
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        IAcsClient client = new DefaultAcsClient(profile);
        // クライアントの再試行ポリシーを指定します。
        client.setSysRetryPolicy(RetryPolicy.none());
        // 操作を呼び出します。この例では、CommonRequest が使用されています。Alibaba Cloud サービスの SDK にカプセル化された操作を呼び出す場合は、<APIName>Request を使用します。
        CommonRequest request = new CommonRequest();
        // リクエストの再試行ポリシーを指定します。リクエストの再試行ポリシー設定は、クライアントの再試行ポリシー設定よりも優先されます。
        // デフォルトの再試行ポリシーを使用し、高度なバックオフメカニズムを有効にします。
        // request.setSysRetryPolicy(RetryPolicy.defaultRetryPolicy(true));
        
        // カスタム再試行ポリシーを使用します。
        // 再試行をトリガーするステータスコードを指定します。
        Set<RetryCondition> retryConditions = new HashSet<RetryCondition>();
        Set<Integer> statusCodes = new HashSet<Integer>();
        statusCodes.add(500); // http ステータスコード
        statusCodes.add(501); // http ステータスコード
        retryConditions.add(StatusCodeCondition.create(statusCodes));

        // 再試行をトリガーする例外を指定します。
        Set<Class<?  extends Exception>> exceptions = new HashSet<Class<?  extends Exception>>();
        exceptions.add(SocketTimeoutException.class); // 例外
        exceptions.add(IOException.class); // 例外
        retryConditions.add(ExceptionsCondition.create(exceptions));

        // 再試行を制限するステータスコードを指定します。
        Set<RetryCondition> throttlingConditions = new HashSet<RetryCondition>();
        Set<Integer> code = new HashSet<Integer>();
        code.add(429); // 再試行を制限する HTTP ステータスコードを指定します。この例では、ステータスコード 429 が返された場合、再試行は禁止されます。
        throttlingConditions.add(StatusCodeCondition.create(code));

        RetryPolicy retryPolicy = RetryPolicy.builder()
                .maxNumberOfRetries(3) // 最大再試行回数。
                .maxDelayTimeMillis(20 * 1000) // 最大再試行間隔。間隔を超えると、再試行は実行されません。
                .retryConditions(retryConditions) // 再試行をトリガーするために使用されるポリシー。
                .enableAliyunThrottlingControl(true) // スロットリング制御のために Alibaba Cloud によって提供されるスロットリングポリシーを有効にします。
                .throttlingConditions(throttlingConditions) // 再試行を制限するための独自のポリシーを記述できます。
                .build();
        request.setSysRetryPolicy(retryPolicy);

        try {
            // 操作を呼び出します。この例では、CommonRequest が使用されています。Alibaba Cloud サービスの SDK にカプセル化された操作を呼び出す場合は、<APIName>Request を使用します。
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
            if (ThrottlingException.class.isAssignableFrom(e.getCause().getClass())) {
                // スロットリング例外は ClientException にカプセル化されています。
            }
        }
    }
}