Я новичок в использовании ThreadPoolTaskExecutor
и CompletableFuture
для Asyn c операций. Поскольку разрабатываемый мной сервис должен иметь хорошую скорость и производительность не должна снижаться, мне пришлось использовать вызовы Asyn c. Однако я не уверен, что не так в коде, служба отлично справляется с отдельными запросами, но после загрузки службы или выполнения нагрузочного теста служба перестает отвечать, она застревает при отправке запроса от почтальона после загрузки, и он показывает «Исключение тайм-аута сокета: время ожидания чтения» в Soap результатах нагрузочного теста пользовательского интерфейса. Ниже приводится операция уровня обслуживания:
@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. Увеличение этого значения также не решает проблему. Второй вызов службы очень мал и возвращает данные в миллисекундах, и это, вероятно, не вызывает проблемы. Кто-нибудь, пожалуйста, помогите мне это исправить. Я думал, что увеличение размера основного пула, максимального размера пула или тайм-аута сокета исправит это, но этого не произошло. Таймаут чтения исключения тайм-аута сокета не должен происходить при увеличении тайм-аута сокета, но это не исправляет.