ThreadPoolTaskExecutor 核心和最大池大小

问题描述 投票:0回答:1

我有一个 Spring Boot 应用程序,我们必须对第 3 方 REST 服务进行一些 http 调用。我们可能需要拨打 1 个电话或数千个电话。

我正在使用 @Async Spring Boot 注释和 CompletableFuture,如下所示:

    long start = System.nanoTime();
    List<String> list = new ArrayList<>();
    List<CompletableFuture<List<String>>> allFutures = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        allFutures.add(httpClient.getStringAsync("Hello"));
    }
    List<String> unwrappedFutures = allFutures.stream()
            .map(CompletableFuture::join)
            .flatMap(List::stream)
            .collect(Collectors.toList());

    list.addAll(unwrappedFutures);
    long duration = (System.nanoTime() - start) / 1_000_000;
    log.info("Done in {} msecs", duration);

此代码大约需要 2 分钟才能对 getStringAsync() 方法进行 1000k 次调用,该方法有 1 秒的延迟。

在我的笔记本电脑上(“Runtime.getRuntime().availableProcessors()”显示有 12 个核心)或在 EKS 集群(现在核心数似乎是 1 个)上处理所需的时间相同。

我想我必须配置 ThreadPoolTaskExecutor,以便可用的核心数量越多,处理所需的时间就越少。

但是,我不太确定如何确定核心、最大池大小和队列容量。

我想知道池大小是否必须等于列表中的项目数?也就是说,如果列表有 1000 个项目,这意味着我们必须对远程服务进行 1000 次调用,那么我们需要 1000 个线程吗?看起来很多。

java spring multithreading spring-boot completable-future
1个回答
1
投票

添加我的发现:

如果我将

ThreadPoolTaskExecutor
核心和最大大小设置为 12(我的笔记本电脑上的核心数量),至少
Runtime.getRuntime().availableProcessors()
显示的是这样的,则平均 1.4 分钟内进行 1000K 次调用。

如果我将

ThreadPoolTaskExecutor
核心和最大大小设置为 100,则平均 10 秒内进行 1000K 次调用。

如果我将

ThreadPoolTaskExecutor
核心和最大大小设置为 1000,则平均 1.4 秒内进行 1000K 次调用。这听起来很吸引人。但是,我正在我的笔记本电脑上进行隔离测试,在真实场景中会有很多其他事件正在处理,所以我认为这并不理想。

© www.soinside.com 2019 - 2024. All rights reserved.