Java Jetty如何处理线程和线程池,它使用了太多的内存

Java Jetty如何处理线程和线程池,它使用了太多的内存,java,api,server,jetty,microservices,Java,Api,Server,Jetty,Microservices,使用图表运行服务器微服务: 但是我看到,init24线程有请求线程 增加32个线程,处理后减少为24个线程 关闭线程的过程很慢,释放内存也很慢 那个问题有多重要?谢谢查看。您的图表不正确 Jetty有一个用于所有操作的单一线程池 一根线就是一根线就是一根线 选择器/接受器/请求/异步处理/异步读取/异步写入/websocket/代理/客户端/等之间没有区别 最后一点,在Jetty 9.4.30.v20200611中,Jetty中大约有93种不同的东西可以使用线程池中的线程,这完全取决于您的应用

使用图表运行服务器微服务:

但是我看到,init24线程有请求线程 增加32个线程,处理后减少为24个线程

关闭线程的过程很慢,释放内存也很慢


那个问题有多重要?谢谢查看。

您的图表不正确

Jetty有一个用于所有操作的单一线程池

一根线就是一根线就是一根线

选择器/接受器/请求/异步处理/异步读取/异步写入/websocket/代理/客户端/等之间没有区别

最后一点,在Jetty 9.4.30.v20200611中,Jetty中大约有93种不同的东西可以使用线程池中的线程,这完全取决于您的应用程序正在做什么,您正在使用什么网络协议,以及您决定在Jetty中使用的各种API的哪些功能

回到你的图表

去掉连接队列,这个框就没有意义了。甚至不知道你想在那里记录什么

当线程用于接受程序时,它根本不参与请求/响应处理。它接受连接并将其交给托管选择器,以处理该新连接的实际接受和后续选择器管理

选择器不是线程。有一个使用线程的选择器管理器,它管理NIO层使用的选择器

只有当您在一台多核机器上接近60000个活动并发选择器事件时,配置多于1个选择器才有用,该多核机器上有超过8个专用于Jetty的内核。(不要错误地将并发连接等同于并发选择器事件,您可以轻松地拥有200000个并发连接,并发选择器事件最多为16个。您需要在生产中监控JVM,以了解应用程序选择器负载的实际情况)

Jetty使用了“吃你杀死的东西”线程执行策略,这意味着“线程池队列”并不像图中那样简单(使用fetch/push)

线程创建是一件昂贵的事情(就时间而言),因此它们会在池中尽可能长时间地保持活动状态。在经过适当调优的JVM上创建线程通常比GC操作花费更多的时间。(是的,我们知道这是一个有争议的说法,但我们在过去20年中在许多不同机器、环境和JVM上的经验表明,即使在OpenJDK 14这样的现代JVM上,这一点也是一贯正确的)

根据负载的不同,线程池中的线程创建可以以突发方式进行。 “负载”可以是新连接、连接上的总流量,甚至可以是应用程序中对各种API的需求

随着时间的推移,空闲线程的删除是有意进行的,以减少和/或消除在负载突发期间创建线程的极端成本

Jetty使用
org.eclipse.Jetty.util.thread.ThreadPool
接口处理线程池

每个
ThreadPool
都有一个
ThreadPoolBudget
,Jetty内的各种API都参与其中,以指示所需的操作线程需求。Jetty中有许多API,一旦您开始使用它们,它们就会自动触发在
ThreadPool
中“保留”X个线程的需要,以便始终可用于该API。示例:如果您有一个新的HTTP/2连接,它将在物理连接的生命周期内将线程池上的“保留线程”数增加1(以处理各种子请求的HTTP/2会话),物理连接的存在并不意味着线程池中正在使用线程,只有当选择器和/或API使用触发它时,它才正常使用线程池,使用当前可用的线程。这允许线程池实现管理对“保留线程”的这种需求。这确保始终有一个线程来处理HTTP/2会话和子请求的低级行为(在本例中,最容易将物理连接视为HTTP/2会话及其管理的子选择器)。这种“保留线程”的概念对于在许多关键任务中的正确操作至关重要,否则您会遇到线程不足和许多关键任务

应用程序所需的最小和最大线程数取决于应用程序的行为及其所经历的负载,而不是某些任意的启动配置

根据您选择的
org.eclipse.jetty.util.thread.ThreadPool
的实现,您可以选择不同的选项来调整它处理空闲线程和删除空闲线程等问题的方式

QueuedThreadPool
(Jetty世界中最常见的
ThreadPool
)中,空闲超时控制池中的线程何时被标识为“空闲”和“适合停止”

空闲线程清理将在每个空闲超时间隔一次删除1个空闲线程

一般的建议是,每次必须创建线程时,您都会降低应用程序的速度,以生成对客户端的响应

想要在Jetty中调整线程的开发人员的另一个争论点是,单个线程和单个请求/响应交换之间绝对没有关系。单个请求/响应交换可以跨多个线程处理(有时也可以跨多个线程,具体取决于您选择使用的API)

试图通过操纵线程池来控制具有请求/响应处理的任何内容都是无效的(例如,试图通过设置较低的最大线程数来限制活动并发请求的数量)

他们还说,还要注意应用程序中的线程本地使用