J2EE应用中如何使用executorService进行http调用
How to use executorService to make http call in J2EE application
我想了解一下在无状态 bean 中使用 ManagedExecutorService。基本上我试图在我的 j2EE 应用程序中的一个单独的线程中发送一个 http 调用。 executorService 发送此请求并等待 x 秒数以接收响应,如果在指定秒数内没有响应或出现异常,则再执行一次尝试(X 次),最后给出一个反馈,表明 https 服务调用成功完成或失败。这是我的代码
@SuppressWarnings("EjbEnvironmentInspection")
@Resource
ManagedExecutorService executorService;
public static final long RETRY_DELAY = 3000;
public static final int MAX_RETRIES = 3;
executorService.execute(() -> {
int retry = 0;
Collection<Info> responseInfo = null;
while (responseInfo == null && retry++ < MAX_RETRIES) {
try {
responseInfo = httpsService.requestAccessInfo(requestInfo);
Thread.sleep(RETRY_DELAY);
} catch (Exception e) {
log.error("Error while receiving response retry attempt {}", retry);
}
}
boolean status = filledLockAccessInfo==null ? false : true;
event.fire(regularMessage(status,GENERATION_RESULT);
});
谁能告诉我这样做是否正确。
你不应该强行睡觉(Thread.sleep(RETRY_DELAY);
)。你需要的是可以支持超时的服务的异步调用。
以下两种方法使用可完成的未来 API 的超时和错误处理来实现它。
下面使用递归重试给定的次数:
private static Collection<Info> callService(int retryCount) {
try {
CompletableFuture<Collection<Info>> f = invoke();
return f.get(RETRY_DELAY, TimeUnit.MILLISECONDS);
}catch(TimeoutException te) {
if(retryCount > 0) {
return callService(retryCount - 1);
} else {
throw new RuntimeException("Fatally failed!!");
}
} catch(Exception ee) {
throw new RuntimeException("Unexpectedly failed", ee);
}
}
注意executorService
对象是在supplyAsync
的第二个参数中传递的
private static CompletableFuture<Collection<Info>> invoke() {
return CompletableFuture.supplyAsync(() -> {
//call
return httpsService.requestAccessInfo(requestInfo);;
}, executorService);
}
有了它,你可以简单地用重试次数来调用它:
Collection<Info> responseInfo = callService(MAX_RETRIES);
要异步进行上述调用 运行,您可以将前面的语句替换为:
CompletableFuture.supplyAsync(() -> callService(MAX_RETRIES))
.thenAccept(res -> System.out.println("Result: " + res));
这将在后台进行调用。稍后,您可以查看它是如何完成的:
f.isCompletedExceptionally() //will tell whether it completed with an exception.
我想了解一下在无状态 bean 中使用 ManagedExecutorService。基本上我试图在我的 j2EE 应用程序中的一个单独的线程中发送一个 http 调用。 executorService 发送此请求并等待 x 秒数以接收响应,如果在指定秒数内没有响应或出现异常,则再执行一次尝试(X 次),最后给出一个反馈,表明 https 服务调用成功完成或失败。这是我的代码
@SuppressWarnings("EjbEnvironmentInspection")
@Resource
ManagedExecutorService executorService;
public static final long RETRY_DELAY = 3000;
public static final int MAX_RETRIES = 3;
executorService.execute(() -> {
int retry = 0;
Collection<Info> responseInfo = null;
while (responseInfo == null && retry++ < MAX_RETRIES) {
try {
responseInfo = httpsService.requestAccessInfo(requestInfo);
Thread.sleep(RETRY_DELAY);
} catch (Exception e) {
log.error("Error while receiving response retry attempt {}", retry);
}
}
boolean status = filledLockAccessInfo==null ? false : true;
event.fire(regularMessage(status,GENERATION_RESULT);
});
谁能告诉我这样做是否正确。
你不应该强行睡觉(Thread.sleep(RETRY_DELAY);
)。你需要的是可以支持超时的服务的异步调用。
以下两种方法使用可完成的未来 API 的超时和错误处理来实现它。
下面使用递归重试给定的次数:
private static Collection<Info> callService(int retryCount) {
try {
CompletableFuture<Collection<Info>> f = invoke();
return f.get(RETRY_DELAY, TimeUnit.MILLISECONDS);
}catch(TimeoutException te) {
if(retryCount > 0) {
return callService(retryCount - 1);
} else {
throw new RuntimeException("Fatally failed!!");
}
} catch(Exception ee) {
throw new RuntimeException("Unexpectedly failed", ee);
}
}
注意executorService
对象是在supplyAsync
private static CompletableFuture<Collection<Info>> invoke() {
return CompletableFuture.supplyAsync(() -> {
//call
return httpsService.requestAccessInfo(requestInfo);;
}, executorService);
}
有了它,你可以简单地用重试次数来调用它:
Collection<Info> responseInfo = callService(MAX_RETRIES);
要异步进行上述调用 运行,您可以将前面的语句替换为:
CompletableFuture.supplyAsync(() -> callService(MAX_RETRIES))
.thenAccept(res -> System.out.println("Result: " + res));
这将在后台进行调用。稍后,您可以查看它是如何完成的:
f.isCompletedExceptionally() //will tell whether it completed with an exception.