[英]Java resilience4j Retry policy goes infinite after 2 retries
I am using the resilience4j
Retry policy to call the HttpGet
request and for testing purposes,我正在使用resilience4j
4j 重试策略来调用HttpGet
请求并用于测试目的,
I have set retryOnResult
to retry when HttpGet
request returns 200
status code.我已将retryOnResult
设置为在HttpGet
请求返回200
状态码时重试。
It successfully retries when maxAttempts
is set to 2
.当maxAttempts
设置为2
时,它会成功重试。
For maxAttempts > 2
application goes in infinite state.对于maxAttempts > 2
应用程序进入无限 state。
public class App {
public static void main(String[] args) {
HttpClient client = HttpClients.createDefault();
HttpRequest request = new HttpGet("https://jsonplaceholder.typicode.com/todos/1");
HttpResponse response;
try {
RetryConfig retryConfig = RetryConfig.<HttpResponse>custom().waitDuration(Duration.ofSeconds(2))
.maxAttempts(3).retryOnResult(s -> {
return s.getStatusLine().getStatusCode() == 200;
}).build();
RetryRegistry registry = RetryRegistry.of(retryConfig);
Retry retry = registry.retry("Http client");
retry.getEventPublisher().onRetry(e -> {
System.out.println("Retrying");
});
CheckedFunction0<HttpResponse> retryableSupplier = Retry.decorateCheckedSupplier(retry,
() -> client.execute((HttpUriRequest) request));
response = Try.of(retryableSupplier).get();
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.toString(entity));
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
pom.xml: pom.xml:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-retry</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
Thats not true.这不是真的。 If the number of attempts is greater than maxAttempts, the last result is returned to the client.如果尝试次数大于 maxAttempts,则将最后一个结果返回给客户端。 It's not an infinite loop.这不是一个无限循环。
public static void main(String[] args) {
String response;
RetryConfig retryConfig = RetryConfig.<String>custom().waitDuration(Duration.ofMillis(100))
.maxAttempts(3).retryOnResult(s -> {
return s.contains("Hello");
}).build();
RetryRegistry registry = RetryRegistry.of(retryConfig);
Retry retry = registry.retry("Http client");
retry.getEventPublisher().onRetry(e -> {
System.out.println("Retrying");
});
CheckedFunction0<String> retryableSupplier = Retry.decorateCheckedSupplier(retry,
() -> "Hello World");
response = Try.of(retryableSupplier).get();
System.out.println(response);
}
Results in结果是
Retrying
Retrying
Hello World
The third attempt also "failed", but the result is returned to the client.第三次尝试也“失败”,但结果返回给客户端。
Finally found the root cause.终于找到了根本原因。 Issue is not with the resiliency4j.问题不在于resilency4j。 But in above scenario same HttpGet request is called multiple times in retry scenario.但在上述场景中,在重试场景中多次调用相同的 HttpGet 请求。 And by default httpclient creates a pool with size of 2 .默认情况下httpclient 创建一个大小为 2 的池。 So after 2 is used, it waits indefinitely trying to get the third connection from the pool.所以在使用 2 之后,它会无限期地等待尝试从池中获取第三个连接。
Final Working Code:最终工作代码:
public class App {
public static int retryCounter = 0;
public static void main(String[] args) {
int maxAttempts = 4;
HttpClient client = HttpClients.createDefault();
HttpRequest request = new HttpGet("https://jsonplaceholder.typicode.com/todos/1");
HttpResponse response;
try {
RetryConfig retryConfig = RetryConfig.<HttpResponse>custom().waitDuration(Duration.ofSeconds(1))
.maxAttempts(maxAttempts).retryOnResult(s -> {
try {
if (s.getStatusLine().getStatusCode() == 200) {
if (retryCounter < maxAttempts -1) {
s.getEntity().getContent().close();
}
return true;
} else {
return false;
}
} catch (UnsupportedOperationException e1) {
return true;
} catch (IOException e1) {
// TODO Auto-generated catch block
return true;
}
}).build();
RetryRegistry registry = RetryRegistry.of(retryConfig);
Retry retry = registry.retry("Http client");
retry.getEventPublisher().onRetry(e -> {
retryCounter ++;
System.out.println("Retrying" + e.getNumberOfRetryAttempts());
});
CheckedFunction0<HttpResponse> retryableSupplier = Retry.decorateCheckedSupplier(retry, () -> {
HttpResponse res = client.execute((HttpUriRequest) request);
return res;
});
response = (CloseableHttpResponse) Try.of(retryableSupplier).get();
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.toString(entity));
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block`enter code here`
e.printStackTrace();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.