我是ThreadPoolTaskExecutor
和CompletableFuture
进行异步操作的新手。由于我正在开发的服务应具有良好的速度,并且性能不应受到影响,因此我不得不利用Async调用。但是,我不确定代码中的错误是什么,该服务对单个请求执行得很好,但是一旦服务上发生负载或执行了负载测试,该服务就会停止响应,并在加载后陷入邮递员的发送请求中,在Soap UI负载测试结果中显示“套接字超时异常:读取超时”。
以下是服务级别操作:
@Async
public CompletableFuture<FindWorkOrdersResponse> findWorkOrders(BusinessUnit businessUnit,
FindWorkOrdersRequest findWorkOrdersRequest) {
CompletableFuture<FindWorkOrdersResponse> result = null;
try {
result = CompletableFuture.supplyAsync(() -> {
return ibsAdapter.findWorkOrders(businessUnit, findWorkOrdersRequest);
}, taskExecutor).thenApplyAsync(findWorkOrdersResp -> {
if (findWorkOrdersResp.getWorkOrders() != null && !findWorkOrdersResp.getWorkOrders().isEmpty()) {
findWorkOrdersResp.getWorkOrders().parallelStream().forEach(wo -> {
wo.setInstallerInfo(mustangAdapter.getCustomer(businessUnit, wo.getServiceProviderId()));
});
}
return findWorkOrdersResp;
}, taskExecutor);
} catch (RejectedExecutionException e) {
logger.warn(
"FindWorkOrders was rejected for async execution, falling back to non-critical execution mode: {}",
e.getMessage());
}
return result;
}
从第一个服务调用返回的数据是大小为50的列表,并且针对每个索引进行第二个服务调用。 任务执行程序设置如下:
@Bean("threadPoolTaskExecutor")
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("Async-");
executor.setCorePoolSize(MdcConstants.CORE_POOL_SIZE);
executor.setMaxPoolSize(MdcConstants.MAX_POOL_SIZE);
executor.setQueueCapacity(MdcConstants.QUEUE_CAPACITY);
//executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
executor.setAllowCoreThreadTimeOut(true);
executor.setKeepAliveSeconds(2);
executor.setTaskDecorator(runnable -> {
Map<String, String> mdcContext = MDC.getCopyOfContextMap();
return () -> {
try {
if (mdcContext != null) {
MDC.setContextMap(mdcContext);
}
runnable.run();
} finally {
MDC.clear();
}
};
});
return executor;
}
核心池大小和最大池大小设置为以下值:
public static final Integer CORE_POOL_SIZE=2;
public static final Integer MAX_POOL_SIZE=100;
public static final Integer QUEUE_CAPACITY=0;
从ibs适配器服务调用中退出的套接字时间设置为600000。增加此值也不能解决问题。第二个服务调用非常小,以毫秒为单位返回数据,这可能不会引起问题。有人请让我解决这个问题。我以为增加核心池大小,最大池大小或套接字超时将解决此问题,但事实并非如此。套接字超时异常读取超时不应在套接字超时增加时发生,但不能解决。