【发布时间】:2020-09-24 05:56:59
【问题描述】:
如何在多次失败的异步请求调用后耗尽重试次数? 我正在使用AsyncHttpClient 向我们的服务器发送请求。如果出现请求超时、连接异常等情况,我希望客户端重试 N 次并抛出自定义异常。调用方法应该收到此异常,否则可以不处理。
// calls post
public void call(String data) throws CustomException {
asyncHttpClient.post(data, 10);
}
// posts data to http endpoint
public void post(String data, int retries) throw CustomException {
// if retries are exhausted, throw CustomException to call()
if (retry <= 0) {
throw new CustomException("exc");
}
BoundRequest request = httpClient.preparePost("http_endpoint");
ListenableFuture<Response> responseFuture = httpClient.post(request);
responseFuture.addListener(() -> {
Response response = null;
int status = 0;
try {
response = responseFuture.get();
status = response.getStatusCode();
// HTTP_ACCEPTED = {200, 201, 202}
if (ArrayUtils.contains(HTTP_ACCEPTED, status)) {
// ok
} else {
sleep(10);
post(data, retry - 1);
}
} catch (InterruptedException e) {
sleep(10);
post(data, retry - 1);
} catch (ExecutionException e) {
// ConnectionException
// RequestTimeoutException
sleep(10); // 10 seconds
post(data, retry - 1);
} catch (Exception e) {
sleep(10); // 10 seconds
post(data, retry - 1 );
} finally {
responseFuture.done();
}
}, Runnable::run);
}
这种方法有几个问题:
- 使用递归调用重试。
-
CustomException似乎从未被抛出,并且在重试 == 0 后,控件返回到finally块。
...
} catch (ExecutionException e) {
// ConnectionException
// RequestTimeoutException
sleep(10); // 10 seconds
try {
post(data, retry - 1);
} catch (CustomException e) {
}
}
...
【问题讨论】:
-
您正在使用哪些软件包或库?改造?好的http?凌空抽射?完整地解释你的代码和你正在使用这些代码的包。
-
responseFuture的实例是什么?该声明未包含在提供的代码中。 -
它是
ListenableFuture<Response>的一个实例,编辑了代码。 -
到目前为止,您对这两个答案的满意程度如何?它们中的任何一个都满足您的需求吗?
-
在你最后的 sn-p 中(在问题 #2 下),你在封闭的
catch(ExecutionException e){…}catch(CustomException e){…}/i> 块。但是,CustomException唯一出现在您较大的第一个 sn-p 中的是顶部的if (retry <= 0) {…}。您从大型 sn-p 中省略嵌套的catch(CustomException e){…}并仅在不同的 sn-p 中单独列出它的意图是什么?它在更大的 sn-p 中不存在有什么意义吗?您将其拆分的方式尚不清楚您是否打算使用它。 TIA。
标签: java asynchttpclient