O SDK para Java oferece suporte a políticas de nova tentativa configuráveis que permitem controlar quais erros acionam novas tentativas, definir o número máximo de repetições e aplicar backoff exponencial.
Um mecanismo de nova tentativa e uma política de limitação foram adicionados. Para obter mais informações, consulte Mecanismo avançado de backoff baseado na política de limitação.
A biblioteca principal aliyun-java-sdk-core V4.6.0 ou posterior oferece suporte ao mecanismo de nova tentativa e fornece um esquema avançado de backoff baseado na política de limitação. Para obter mais informações, consulte Mecanismo avançado de backoff baseado na política de limitação. Adicione a seguinte dependência do Maven:
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.0</version>
</dependency>
Mecanismo de nova tentativa
Desativar o mecanismo de nova tentativa
O mecanismo de nova tentativa vem desativado por padrão. Para desativá-lo explicitamente, defina a política de nova tentativa como none no nível do cliente ou da solicitação:
// 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());
Políticas de nova tentativa
O SDK oferece suporte a três tipos de políticas de nova tentativa:
Especificar exceções.
Especificar códigos de status HTTP.
Especificar cabeçalhos de resposta HTTP.
Essas três condições são independentes. Se qualquer condição for atendida, o SDK repete a solicitação ou interrompe as novas tentativas. É possível criar políticas que acionem repetições e políticas que as restrinjam.
Os exemplos a seguir mostram como configurar políticas para acionar ou restringir novas tentativas:
-
Crie uma coleção de condições de nova tentativa:
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)); -
Crie uma coleção de condições para restringir novas tentativas:
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)); -
Adicione condições ao 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();
Os intervalos entre tentativas são calculados com um algoritmo de backoff exponencial. O algoritmo EqualJitter determina o tempo de espera antes de cada nova tentativa.
Configurar definições avançadas das condições de nova tentativa
A seção a seguir descreve em detalhes os três tipos de condições integradas.
-
StatusCodeCondition
Armazena uma coleção de inteiros. O SDK compara cada inteiro com o código de status HTTP retornado para determinar se deve acionar ou restringir novas tentativas.
-
ExceptionsCondition
Armazena uma coleção de exceções. O SDK compara cada exceção com a exceção lançada durante a chamada para determinar se deve acionar ou restringir novas tentativas.
-
HeadersCondition
Armazena um mapa com estrutura complexa. A chave do mapa corresponde à chave do cabeçalho de resposta, e o valor é avaliado pela interface Pattern (com.aliyuncs.policy.retry.pattern.Pattern). O padrão verifica se o valor do cabeçalho de resposta contém uma string específica ou é igual a um determinado valor.
Dois padrões têm suporte: AliyunThrottlingPattern e SimplePattern. O AliyunThrottlingPattern aplica a política de limitação fornecida pela Alibaba Cloud. Para obter mais informações, consulte Mecanismo avançado de backoff baseado na política de limitação. O SimplePattern verifica se os valores são iguais.
-
Para personalizar a interface Pattern, implemente os três métodos a seguir:
meetState(): retorna true quando a regra corresponde.
escapeTime(): retorna o tempo de escape em milissegundos. Este método se aplica apenas a políticas de restrição de nova tentativa. Se o valor retornado não for -1, as novas tentativas serão pausadas pela duração especificada em vez de serem restritas permanentemente. O SDK aguarda o término do tempo de escape antes de tentar novamente. Se esse valor exceder o intervalo máximo de nova tentativa, a solicitação falhará imediatamente.readFormHeadersContent(String content): analisa e atribui um valor do cabeçalho. Reutilize diretamente a implementação do SimplePattern.
-
Condições personalizadas
-
Para criar condições personalizadas, implemente a interface RetryCondition com os dois métodos a seguir:
meetState(RetryPolicyContext var1): avalia se a condição de nova tentativa foi atendida com base no contexto.
escapeTime(RetryPolicyContext var1): calcula o tempo de escape. Este método se aplica apenas a políticas de restrição. Para políticas de acionamento, retorne -1.
-
Código de exemplo completo
Código de exemplo:
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.
}
}
}
}