Tomcat7并发和线程数
最近一直在解决线上一个问题,表现是:
Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池满了,日志看很多请求超过了1s。
服务器性能很好,Tomcat版本是7.0.54,配置如下:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="3000" minSpareThreads="800"/> <Connector executor="tomcatThreadPool" port="8084"
protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="60000"
keepAliveTimeout="30000"
maxKeepAliveRequests="8000"
maxHttpHeaderSize="8192"
URIEncoding="UTF-8"
enableLookups="false"
acceptCount="1000"
disableUploadTimeout="true"
redirectPort="8443" />
事后thread dump看其实真正处于RUNNABLE状态的线程很少,绝大部分线程都处于TIMED_WAITING状态:

于是大伙都开始纠结为什么线程会涨到3000,而且发现即使峰值过了线程数并不会降下来。我们首先想到的是:
后端应用的处理瞬间比较慢,“堵住了”导致前端线程数涨了起来。
但是优化一个版本上线后发现虽然涨的情况有所好转,但是最终线程池还是会达到3000这个最大值。
==================================分割线=========================================
以上是大背景,中间的过程省略,直接跟各位说下目前我得到的结论:
1、首先是为什么线程不释放的问题?
简单说下我验证的Tomcat(7.0.54)线程池大概的工作机制
- Tomcat启动时如果没有请求过来,那么线程数(都是指线程池的)为0;
- 一旦有请求,Tomcat会初始化minSapreThreads设置的线程数;
- Tomcat不会主动对线程池进行收缩,除非确定没有任何请求的时候,Tomcat才会将线程池收缩到minSpareThreads设置的大小;
- Tomcat6之前的版本有一个maxSpareThreads参数,但是在7中已经移除了,所以只要前面哪怕只有一个请求,Tomcat也不会释放多于空闲的线程。
至于Tomcat为什么移除maxSpareThreads这个参数,我想也是出于性能的考虑,不停的收缩线程池性能肯定不高,而多余的线程处于等待状态的好处是一有新请求过来立刻可以处理。
- 而且大量的Tomcat线程处于等待状态不会消耗CPU,但是会消耗一些JVM存储。
补充:上面标红的一句有点问题,进一步验证发现只有使用Keep-Alive(客户端和服务端都支持)时才是这种表现,如果客户端没有使用Keep-Alive那么线程会随着TCP连接的释放而回收。
Tomcat中Keep-Alive相关的参数:
maxKeepAliveRequests:
The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.
keepAliveTimeout:
The number of milliseconds this Connector will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the connectionTimeout attribute. Use a value of -1 to indicate no (i.e. infinite) timeout.
2、为什么线程池会满?
这是我现在纠结的核心。到底是不是应用的性能慢导致的,我现在的结论是有关系,但关键是并发。
- Tomcat的线程池的线程数跟你的瞬间并发有关系,比如maxThreads设置为1000,当瞬间并发达到1000那么Tomcat就会起1000个线程来处理,这时候跟你应用的快慢关系不大。
那么是不是并发多少Tomcat就会起多少个线程呢?这里还跟Tomcat的这几个参数设置有关系,看官方的解释是最靠谱的:
maxThreads:
The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 200. If an executor is associated with this connector, this attribute is ignored as the connector will execute tasks using the executor rather than an internal thread pool.
maxConnections:
The maximum number of connections that the server will accept and process at any given time. When this number has been reached, the server will accept, but not process, one further connection. This additional connection be blocked until the number of connections being processed falls below maxConnections at which point the server will start accepting and processing new connections again. Note that once the limit has been reached, the operating system may still accept connections based on the
acceptCountsetting. The default value varies by connector type. For BIO the default is the value of maxThreads unless an Executor is used in which case the default will be the value of maxThreads from the executor. For NIO the default is10000. For APR/native, the default is8192.……
acceptCount:
The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 100.
minSpareThreads:
The minimum number of threads always kept running. If not specified, the default of
10is used.
我简单理解就是:
maxThreads:Tomcat线程池最多能起的线程数;
maxConnections:Tomcat最多能并发处理的请求(连接);
acceptCount:Tomcat维护最大的对列数;
minSpareThreads:Tomcat初始化的线程池大小或者说Tomcat线程池最少会有这么多线程。
比较容易弄混的是maxThreads和maxConnections这两个参数:
maxThreads是指Tomcat线程池做多能起的线程数,而maxConnections则是Tomcat一瞬间做多能够处理的并发连接数。比如maxThreads=1000,maxConnections=800,假设某一瞬间的并发时1000,那么最终Tomcat的线程数将会是800,即同时处理800个请求,剩余200进入队列“排队”,如果acceptCount=100,那么有100个请求会被拒掉。
注意:根据前面所说,只是并发那一瞬间Tomcat会起800个线程处理请求,但是稳定后,某一瞬间可能只有很少的线程处于RUNNABLE状态,大部分线程是TIMED_WAITING,如果你的应用处理时间够快的话。所以真正决定Tomcat最大可能达到的线程数是maxConnections这个参数和并发数,当并发数超过这个参数则请求会排队,这时响应的快慢就看你的程序性能了。
Tomcat7并发和线程数的更多相关文章
- IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的
IIS连接数 一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,这边先从普通不懂代码用户角度理解IIS连接数 顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫" ...
- 你真的了解:IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的最大工作进程数 吗?
原文链接:http://www.cnblogs.com/yinhaichao/p/4060209.html?utm_source=tuicool&utm_medium=referral 一般购 ...
- 转载:IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数
一.IIS连接数 一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫“IIS限制连接数”. 客户请求的连接内容包括: [ ...
- IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数
一.IIS连接数 一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫“IIS限制连接数”. 客户请求的连接内容包括: [ ...
- IIS:连接数、并发连接数、最大并发工作线程数、应用程序池的队列长度、应用程序池的最大工作进程数详解
Internet Information Services(IIS,互联网信息服务),是由微软公司提供的基于运行Microsoft Windows的互联网基本服务.最初是Windows NT版本的可选 ...
- IIS最大并发连接数 = 队列长度 + IIS最大并发工作线程数
深入理解IIS的多线程工作机制 首先让我们来看看IIS里面的这2个数字:最大并发连接数,队列长度.先说这2个数字在哪里看. 最大并发连接数:在IIS中选中一个网站,右键网站名称,在右键菜单中找到并 ...
- IIS连接数、并发连接数、最大并发工作线程数、应用程序池的队列长度、应用程序池的最大工作进程数详解
IIS:连接数.并发连接数.最大并发工作线程数.应用程序池的队列长度.应用程序池的最大工作进程数详解 iis性能指标的各种概念:连接数.并发连接数.最大并发工作线程数.应用程序池的队列长度.应用程序池 ...
- 一个使用高并发高线程数 Server 使用异步数据库客户端造成的超时问题
现象 今天在做一个项目时, 将 tomcat 的 maxThreads 加大, 加到了 1024, tomcat 提供的服务主要是做一些运算, 然后插入 redis, 查询 redis, 最后将任务返 ...
- IIS并发瓶颈线程数的限制
.NET线程池最大线程数的限制-记一次IIS并发瓶颈 https://www.cnblogs.com/7rhythm/p/9964543.html .NET ThreadPool 最大线程数的限制 I ...
随机推荐
- OpenGL ES 3.0之Shader and program(七)
着色器对象和程序对象是使用着色器渲染的2种基本的对象类型.一个着色器对象可以当做是一个C编译器,而程序对象作为连接器.一个编译器生成目标代码(如.OBJ,.o文件),对象文件完成创建后,C连接器将该对 ...
- tail 命令
转自:http://www.cnblogs.com/peida/archive/2012/11/07/2758084.html tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项 ...
- 造轮子 | 怎样设计一个面向协议的 iOS 网络请求库
近期开源了一个面向协议设计的网络请求库 MBNetwork,基于 Alamofire 和 ObjectMapper 实现,目的是简化业务层的网络请求操作. 须要干些啥 对于大部分 App 而言,业务层 ...
- asp.net 字符串反序列化
//在大多数情况下,dynamic 类型与 object 类型的行为是一样的. //Dynamic 在通过 dynamic 类型实现的操作中,该类型的作用是绕过编译时类型检查, 改为在运行时解析这些操 ...
- 使用SqlBulkCopy类实现导入excel表格
前言: 上篇博客介绍了SqlBulkCopy类批量操作数据库的相关操作,最后提到了可以使用这个类实现excel文件导入数据库,接下来我做简单介绍. 首先说一下思路: 把excel中的数据读出来并放入到 ...
- JS base64加解密解决传输的url各种编码问题
网上拷贝的,废话少说,直接上代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...
- HttpLuaModule——翻译(一)
最近经常使用春哥和小哲老师写的NGINX-LUA,非常苦于没有中文文档,特别是向我这种英文水平实在有限的同学,所以将遇到的模块记录下来,供以后参考!原文:http://wiki.nginx.org/H ...
- hdu 4336 概率dp + 状压
hdu 4336 小吃包装袋里面有随机赠送一些有趣的卡片,如今你想收集齐 N 张卡片.每张卡片在食品包装袋里出现的概率是p[i] ( Σp[i] <= 1 ), 问你收集全部卡片所需购买的食品数 ...
- GoldenGate 12c + Oracle 12c Multitenant Container databases
下面为GoldenGate 12c + Oracle 12c Multitenant Container databases例子 1.安装OGG 源 端OGG: C:\Oracle\product\1 ...
- RPC远程调用概念 && demo实例
RPC是指远程过程调用,直观说法就是A通过网络调用B的过程方法. 也就是说两台serverA.B,一个应用部署在Aserver上,想要调用Bserver上应用提供的函数/方法,因为不在一个内存空间,不 ...