Java 的 ThreadPoolExecutor 可以在应用程序级别充当负载均衡器吗?

Posted

技术标签:

【中文标题】Java 的 ThreadPoolExecutor 可以在应用程序级别充当负载均衡器吗?【英文标题】:Can Java's ThreadPoolExecutor act as a load balancer at application level? 【发布时间】:2020-12-11 05:11:57 【问题描述】:

使用 ThreadPoolExecutor,我们可以通过限制最大线程数来定义服务器应处理的最大请求数。

此外,ThreadPoolExecutor 将额外的传入请求添加到线程队列。

因此,在应用程序级别,可以使用 ThreadPoolExecutor 编写基于应用程序要求的自定义逻辑来限制或拒绝某些请求。

因此,它可以在应用程序级别充当负载均衡器吗?

【问题讨论】:

好吧,它并没有真正平衡任何东西;负载均衡器通常在多台机器之间分配任务。此外,当可用资源不堪重负时,负载均衡器可能应该减少一些负载(即拒绝请求)。 ThreadPoolExecutor 两者都不做。所以,不,它不是真正的负载均衡器。 @danielkullmann, 2) 指出这不是真的。您可以将有界队列传递给 ThreadPoolExecutor 的构造函数,如果队列已满,则新提交的任务将被丢弃。有关详细信息,请参阅 RejectedExecutionHandler。 @IvanBabanin 啊!感谢您清除它! 【参考方案1】:

理论上,我们可以通过使用ExecutorServices 来优化资源利用率。在实践中,存在一些限制。例如,ThreadPoolExecutor 计划是任务。任务在 Java 线程上运行,Java 线程映射在 OS 线程上。 Java 线程无法卸载任务,除非它定期或异常完成。但是,操作系统线程可以卸载 Java 线程并加载另一个进程。

Java 线程无法卸载未完成任务这一事实的后果是,系统可能会隶属于Thread starvation:当(父)任务创建新(子)任务并且父任务需要以下结果时子任务继续,我们可以达到一个点,所有 Java 线程都卡在等待子任务完成的父任务上,并且没有线程可以进行,因为没有线程可用于执行子任务。

有一些尝试绕过这个瓶颈,例如ForkJoinPool 可能会启动额外的Threads 来解决线程饥饿问题。但是,不能保证始终避免或解决线程饥饿问题(这也是 vert.x 或 webflux 等框架拒绝阻塞操作或将它们委托给专用线程的原因之一)。

Furhtermore - as was mentioned by daniel kullmann in the comments - 负载平衡器尝试平衡工作。在ThreadPoolExecutors 中,有一个共享队列和线程主动拉取任务,所以没有主动平衡。这些是不同的概念。

【讨论】:

“Java 中的线程是绿色线程,它不是操作系统线程。” - 你有支持它的来源吗?我读过相反的说法 @Joni you were right。 java 线程映射到默认线程模型中的 OS 线程。相应地更新我的答案。【参考方案2】:

如果您接受“负载平衡”的广义定义,是的,您可以将 ThreadPoolExecutor 视为一种负载平衡器。

根据负载均衡的广义定义like the one on Wikipedia:

在计算中,负载均衡是指将一组任务分配到一组资源(计算单元)上的过程,目的是提高它们的整体处理效率。

使用线程池执行器,tasks 是您需要运行的 RunnableCallable 的实例。线程池管理的线程是任务分布在其中的资源。线程池旨在通过确保只要有需要执行的任务就没有线程处于空闲状态,从而提高整体处理效率。

另一方面,问题的措辞表明您正在考虑一种不同类型的负载平衡:Web 服务请求分布在服务器机器上,并且您希望在满足服务需求的同时避免任何负载超载特定的机器。在这种情况下,您可能会使用 ThreadPoolExecutor 作为负载平衡系统的一部分,但它本身并不是一个完整的解决方案:ThreadPoolExecutor 仅在一台机器上的线程之间分配任务。它没有办法响应来自远程机器的请求,也没有向远程机器发送任务。

【讨论】:

以上是关于Java 的 ThreadPoolExecutor 可以在应用程序级别充当负载均衡器吗?的主要内容,如果未能解决你的问题,请参考以下文章

java多线程---------java.util.concurrent并发包----------ThreadPoolExecutor

java进阶之路-java中的ThreadPoolExecutor

深入理解java线程池—ThreadPoolExecutor

java ThreadPoolExecutor

Android Java 线程池 ThreadPoolExecutor源代码篇

java线程池之ThreadPoolExecutor