使用ThreadPoolTask​​Executor

时间:2020-08-03 17:14:26

标签: multithreading spring-boot java.util.concurrent completable-future threadpoolexecutor

我是ThreadPoolTaskExecutorCompletableFuture进行异步操作的新手。由于我正在开发的服务应具有良好的速度,并且性能不应受到影响,因此我不得不利用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。增加此值也不能解决问题。第二个服务调用非常小,以毫秒为单位返回数据,这可能不会引起问题。有人请让我解决这个问题。我以为增加核心池大小,最大池大小或套接字超时将解决此问题,但事实并非如此。套接字超时异常读取超时不应在套接字超时增加时发生,但不能解决。

0 个答案:

没有答案