Le SDK Java prend en charge des politiques de nouvelle tentative configurables. Elles permettent de contrôler les erreurs déclenchant une nouvelle tentative, de définir le nombre maximal de tentatives et d'appliquer un backoff exponentiel.
Un mécanisme de nouvelle tentative et une politique de limitation ont été ajoutés. Pour plus d'informations, consultez Mécanisme de backoff avancé basé sur la politique de limitation.
La bibliothèque principale aliyun-java-sdk-core V4.6.0 ou ultérieure prend en charge le mécanisme de nouvelle tentative et fournit un schéma de backoff avancé basé sur la politique de limitation. Pour plus d'informations, consultez Mécanisme de backoff avancé basé sur la politique de limitation. Ajoutez la dépendance Maven suivante :
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.0</version>
</dependency>
Mécanisme de nouvelle tentative
Désactiver le mécanisme de nouvelle tentative
Le mécanisme de nouvelle tentative est désactivé par défaut. Pour le désactiver explicitement, définissez la politique de nouvelle tentative à none au niveau du client ou de la requête :
// Specify a retry policy for the client to disable the retry mechanism.
client.setSysRetryPolicy(RetryPolicy.none());
// Specify a retry policy for the request. The retry policy configuration of the request takes precedence over the retry policy configuration of the client.
request.setSysRetryPolicy(RetryPolicy.none());
Politiques de nouvelle tentative
Le SDK prend en charge trois types de politiques de nouvelle tentative :
Spécifiez des exceptions.
Spécifiez des codes de statut HTTP.
Spécifiez des en-têtes de réponse HTTP.
Ces trois conditions sont indépendantes. Dès qu'une condition est remplie, le SDK effectue une nouvelle tentative ou arrête les tentatives. Vous pouvez créer des politiques qui déclenchent les nouvelles tentatives ainsi que des politiques qui les restreignent.
Les exemples suivants montrent comment configurer des politiques pour déclencher ou restreindre les nouvelles tentatives :
-
Créez une collection de conditions de nouvelle tentative :
Set<RetryCondition> retryConditions = new HashSet<RetryCondition>(); // Example of conditions // Specify status codes to trigger a retry. In the following example, a retry is performed when the status code 500 or 501 is returned. Set<Integer> statusCodes = new HashSet<Integer>(); statusCodes.add(500); // http statusCode statusCodes.add(501); // http statusCode // Add the status code configuration to the policy that is used to trigger a retry. retryConditions.add(StatusCodeCondition.create(statusCodes)); // Specify exceptions to trigger a retry. In the following example, a retry is performed when a SocketTimeoutException or IOException is thrown. Set<Class<? extends Exception>> exceptions = new HashSet<Class<? extends Exception>>(); exceptions.add(SocketTimeoutException.class); // exception exceptions.add(IOException.class); // exception // Add the exception configuration to the policy that is used to trigger a retry. retryConditions.add(ExceptionsCondition.create(exceptions)); -
Créez une collection de conditions pour restreindre les nouvelles tentatives :
Set<RetryCondition> throttlingConditions = new HashSet<RetryCondition>(); // Example of conditions // Specify status codes to restrict a retry. In the following example, a retry is prohibited when the status code 429 is returned. Set<Integer> code = new HashSet<Integer>(); code.add(429); // Specify an HTTP status code to restrict a retry. In this example, a retry is prohibited if the status code 429 is returned. // Add the status code configuration to the policy that is used to restrict retires. throttlingConditions.add(StatusCodeCondition.create(code)); -
Ajoutez les conditions à RetryPolicy :
RetryPolicy retryPolicy = RetryPolicy.builder() .maxNumberOfRetries(3) // The maximum number of retries. .maxDelayTimeMillis(20 * 1000) // The maximum retry interval. Unit: milliseconds. If the specified duration is exceeded, no retries are performed. .retryConditions(retryConditions) // The policy that is used to trigger retries. . .throttlingConditions(throttlingConditions) // The policy that is used to restrict retries. .build();
Les intervalles entre les tentatives sont calculés à l'aide d'un algorithme de backoff exponentiel. L'algorithme EqualJitter détermine le temps d'attente avant chaque nouvelle tentative.
Configurer les paramètres avancés des conditions de nouvelle tentative
Cette section décrit en détail les trois types de conditions intégrées.
-
StatusCodeCondition
Stocke une collection d'entiers. Le SDK compare chaque entier au code de statut HTTP retourné afin de déterminer s'il faut déclencher ou restreindre les nouvelles tentatives.
-
ExceptionsCondition
Stocke une collection d'exceptions. Le SDK compare chaque exception à celle levée lors de l'appel pour décider de déclencher ou de restreindre les nouvelles tentatives.
-
HeadersCondition
Stocke une map à structure complexe. La clé de la map correspond à la clé de l'en-tête de réponse, tandis que la valeur est évaluée via l'interface Pattern (com.aliyuncs.policy.retry.pattern.Pattern). Ce pattern vérifie si la valeur de l'en-tête de réponse contient une chaîne spécifique ou est égale à une valeur donnée.
Deux patterns sont pris en charge : AliyunThrottlingPattern et SimplePattern. AliyunThrottlingPattern applique la politique de limitation fournie par Alibaba Cloud. Pour plus d'informations, consultez Mécanisme de backoff avancé basé sur la politique de limitation. SimplePattern vérifie l'égalité des valeurs.
-
Pour personnaliser l'interface Pattern, implémentez les trois méthodes suivantes :
meetState() : retourne true lorsque la règle correspond.
escapeTime(): retourne le temps d'échappement en millisecondes. Cette méthode s'applique uniquement aux politiques de restriction des nouvelles tentatives. Si la valeur retournée n'est pas -1, les nouvelles tentatives sont suspendues pendant la durée spécifiée au lieu d'être définitivement interdites. Le SDK attend la fin du temps d'échappement avant de réessayer. Si cette valeur dépasse l'intervalle maximal de nouvelle tentative, la requête échoue immédiatement.readFormHeadersContent(String content) : analyse et attribue une valeur provenant de l'en-tête. Réutilisez directement l'implémentation de SimplePattern.
-
Conditions personnalisées
-
Pour créer des conditions personnalisées, implémentez l'interface RetryCondition avec les deux méthodes suivantes :
meetState(RetryPolicyContext var1) : évalue si la condition de nouvelle tentative est remplie en fonction du contexte.
escapeTime(RetryPolicyContext var1) : calcule le temps d'échappement. Cette méthode s'applique uniquement aux politiques de restriction. Pour les politiques de déclenchement, retournez -1.
-
Exemple de code complet
Exemple de code :
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) {
// Create and initialize a DefaultAcsClient instance.
DefaultProfile profile = DefaultProfile.getProfile(
// The region ID.
"cn-hangzhou",
// Obtain the AccessKey ID of the RAM user from an environment variable.
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
// Obtain the AccessKey secret of the RAM user from an environment variable.
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
IAcsClient client = new DefaultAcsClient(profile);
// Configure the retry policy at the client level.
client.setSysRetryPolicy(RetryPolicy.none());
// This example uses CommonRequest. The configuration also applies to product-specific SDKs, such as <APIName>Request.
CommonRequest request = new CommonRequest();
// Configure the retry policy at the request level. This configuration has a higher priority than the client-level configuration.
request.setSysRetryPolicy(RetryPolicy.defaultRetryPolicy(true));
// Configure status codes to trigger retries.
Set<RetryCondition> retryConditions = new HashSet<RetryCondition>();
Set<Integer> statusCodes = new HashSet<Integer>();
statusCodes.add(500); // http statusCode
statusCodes.add(501); // http statusCode
retryConditions.add(StatusCodeCondition.create(statusCodes));
// Configure exceptions to trigger retries.
Set<Class<? extends Exception>> exceptions = new HashSet<Class<? extends Exception>>();
exceptions.add(SocketTimeoutException.class); // exception
exceptions.add(IOException.class); // exception
retryConditions.add(ExceptionsCondition.create(exceptions));
// Configure status codes to restrict retries.
Set<RetryCondition> throttlingConditions = new HashSet<RetryCondition>();
Set<Integer> code = new HashSet<Integer>();
code.add(429); // http statusCode, restriction policy. This means a 429 status code restricts retries.
throttlingConditions.add(StatusCodeCondition.create(code));
RetryPolicy retryPolicy = RetryPolicy.builder()
.maxNumberOfRetries(3) // Maximum number of retries.
.maxDelayTimeMillis(20 * 1000) // Maximum retry interval. No more retries are attempted after this time.
.retryConditions(retryConditions) // Policy to trigger retries.
.enableAliyunThrottlingControl(true) // Use the Alibaba Cloud throttling policy for control.
.throttlingConditions(throttlingConditions) // You can also write your own restriction policy.
.build();
try {
// This example uses CommonRequest. The configuration also applies to product-specific SDKs, such as <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())) {
// The throttling exception is encapsulated in ClientException.
}
}
}
}