Multithreading 如何确定Tomcat中的最佳线程数?

Multithreading 如何确定Tomcat中的最佳线程数?,multithreading,tomcat6,Multithreading,Tomcat6,如何确定Tomcat中maxSpare、minSpare和maxThreads、acceptCount等的最佳数量?是否存在现有的最佳实践 我理解这需要基于硬件(例如每个核心),并且只能作为特定硬件上进一步性能测试和优化的基础 多少线程的问题是一个相当大和复杂的问题,不能用简单的经验法则来回答 考虑到您有多少内核对于多线程应用程序很有用,这些应用程序往往会消耗大量CPU,如数字运算等。web应用程序很少出现这种情况,它通常不是被CPU占用,而是被其他因素占用 一个常见的限制是您和其他外部系统之间

如何确定Tomcat中maxSpare、minSpare和maxThreads、acceptCount等的最佳数量?是否存在现有的最佳实践

我理解这需要基于硬件(例如每个核心),并且只能作为特定硬件上进一步性能测试和优化的基础

多少线程的问题是一个相当大和复杂的问题,不能用简单的经验法则来回答

考虑到您有多少内核对于多线程应用程序很有用,这些应用程序往往会消耗大量CPU,如数字运算等。web应用程序很少出现这种情况,它通常不是被CPU占用,而是被其他因素占用

一个常见的限制是您和其他外部系统之间的延迟,最明显的是您的DB。每次请求到达时,它可能会多次查询数据库,这意味着在JDBC连接上传输一些字节,然后等待这些字节到达数据库(即使是在本地主机上仍然存在一个小的滞后),然后等待DB来考虑我们的请求,然后等待数据库处理它。(数据库本身将等待磁盘搜索到某个区域)等等

在这段时间内,线程处于空闲状态,因此另一个线程可以很容易地使用CPU资源来做一些有用的事情。通常会看到40%到80%的时间花在等待DB响应上

连接的另一端也会发生同样的情况。当您的线程将其输出写入浏览器时,客户端连接的速度可能会使您的线程处于空闲状态,等待浏览器确认已收到某个数据包。(几年前,这是一个相当大的问题,最近的内核和JVM使用更大的缓冲区来防止线程以这种方式空闲,但是web应用程序服务器前面的反向代理(即使只是一个httpd)对于避免互联网连接不良的人充当DDOS攻击非常有用:)

考虑到这些因素,线程的数量通常应该比您拥有的内核多得多。即使在一个简单的双核或四核服务器上,您也应该至少配置几十个线程

那么,什么限制了您可以配置的线程数量

首先,每个线程(过去)都会消耗大量资源。每个线程都有一个堆栈,它会消耗RAM。此外,每个线程实际上会在堆上分配一些东西来完成它的工作,再次消耗RAM,而线程之间的切换(上下文切换)对于JVM/OS内核来说是相当繁重的

这使得服务器很难“顺利”运行数千个线程

鉴于此,有许多技术(主要是:尝试、失败、调整、重试)来确定应用程序需要多少线程:

1) 试着理解你的线程在哪里花费时间。有很多好的工具,但即使是jvisualvm profiler也可以是一个很好的工具,或者是一个生成摘要计时统计数据的跟踪方面。他们花在等待外部事物上的时间越多,就越能在空闲时间产生更多线程来使用CPU

2) 确定RAM的使用情况。考虑到JVM将使用一定数量的内存(最明显的是permgen空间,通常高达100兆字节,jvisualvm也会告诉你),与你使用的线程数量无关,试着用一个线程运行,然后用十个线程运行,然后用一百个线程运行,同时用jmeter或其他什么来强调应用程序,看看堆使用率将如何增长。这可能构成一个硬限制

3) 试着确定一个目标。每个用户请求都需要一个线程来处理。如果平均响应时间为“获取”的200毫秒(最好不要考虑加载图像、CSS和其他静态资源),那么每个线程能够每秒服务4/5页。如果期望每个用户每3/4秒“点击”一次(取决于它是一个浏览器游戏还是一个有大量长文本的站点),那么一个线程将“服务于20个并发用户”,不管它是什么意思。如果在高峰时段,你有500个单一用户在一分钟内访问你的站点,那么你需要足够的线程来处理这个问题

4) 碰撞测试达到上限。使用jmeter,在一个备用虚拟机上配置一个具有大量线程的服务器,并查看当超过某个限制时,响应时间将如何变得更糟。与硬件相比,底层操作系统的线程实现在这里更为重要,但无论它遇到什么情况,CPU都会花费更多的时间来尝试运行哪个线程,而不是实际运行它,而且这个数字并不是那么高

5)考虑线程将如何影响其他组件。每个线程可能会使用一个(或多个)到数据库的连接,数据库是否能够处理50/100/500并发连接?即使您使用的是nosql服务器的分片集群,服务器场是否在这些机器之间提供足够的带宽?与web应用服务器在同一台机器上还将运行什么?阿纳奇httpd?乌贼?数据库本身?数据库的本地缓存代理,如mongos或memcached

我见过生产中只有4个线程+4个备用线程的系统,因为该服务器所做的工作只是调整图像大小,因此它几乎100%占用CPU,而其他系统配置在几乎相同的硬件上,具有数百个线程,因为webapp对外部系统进行了大量的SOAP调用,大部分时间都在等待答案

Oce您已经确定了最适合您的webapp的大约最小和最大线程数,然后我通常通过以下方式对其进行配置:

1) 基于RAM、其他外部资源和上下文切换实验的限制,存在绝对最大值,这是绝对不能达到的。因此,使用maxThreads将其限制在该数字的一半或3/4左右

2) 如果应用程序相当快(例如,它公开RESTWebSER)