任务因 ThreadPoolExecutor 中的最大池大小而被拒绝

Task Getting rejected due to max pool size in ThreadPoolExecutor

应用程序已配置 Zuul 和 Eureka 将请求路由到后端服务,在我们进行负载测试之前一切正常。

我开始在我们的负载测试环境中执行 10 个并发请求并在 zuul 网关中收到转发错误,原因是线程池无法为未来任务分配线程并拒绝任务,并出现以下错误。

Caused by: java.util.concurrent.RejectedExecutionException: Task 
java.util.concurrent.FutureTask@70fe89b5 rejected from 
java.util.concurrent.ThreadPoolExecutor@25df1748[Running, pool size = 10, 
active threads = 10, queued tasks = 0, completed tasks = 1502]

我的奇迹;上面的原因,我看到池大小只有 10,10 个线程很忙,很实用,因为我连续发出 10 个请求。

但是我的 corepoolsize 应该比我在这里遇到的计数 10 大得多。是什么导致我的应用程序限制为 10 个池大小,我可以增加我的应用程序中的 corepoolsize 和 maxpoolsize。

问题是您使用的是哪个线程池? 您可以在 Java 中定义各种 ExecutorServices,例如用于未知线程数的缓存线程池,这将解决您的问题(我的一个项目的示例代码):

ExecutorService pool = Executors.newCachedThreadPool();
    for(FluentCreate create: creates) {
        pool.execute(()->{
            try {
                create.execute();
            } catch (JiraException | IOException | ParseException | RestException | URISyntaxException e) {
                e.printStackTrace();
            }
        });
    }
pool.shutdown();
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

如果您能够预测您可以使用固定线程池的任务数量。

Executors.newFixedThreadPool(3);

根据 javadocs,ThreadPoolExecutor 可能会抛出 RejectedExecutionException 有几个原因:

  • 如果请求无法排队,并且无法创建另一个池线程,因为这会超过maxPoolSize

  • 如果执行器上已经调用了shutdown()方法

现在你说你正在使用 "the default" Java 执行器,但你的意思有点不清楚。 (如果你向我们展示了如何获取和使用这个执行器,你的问题会更容易理解!)

但归根结底,池大小不太可能是导致任务被拒绝的问题的原因。如果所有工作人员都很忙,任务 应该 排队。


but I see pool size is only 10, which is not ok in real [life] scenario

在许多现实生活场景中,大小为 10 的池就可以了。但如果它不适合你的场景,你应该考虑创建一个更大(或更小)池的执行器。