文档章节

聊下并发和Tomcat线程数

jepacd
 jepacd
发布于 2016/07/26 14:57
字数 1298
阅读 81
收藏 4

最近一直在解决线上一个问题,表现是: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存储。

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 acceptCount setting. 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 is 10000. For APR/native, the default is 8192.……
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 10 is used.

我简单理解就是:

  • maxThreads - Tomcat线程池最多能起的线程数
  • maxConnections - Tomcat最多能并发处理的请求(连接)
  • acceptCount - Tomcat维护最大的对列数
  • minSpareThreads - Tomcat初始化的线程池大小或者说Tomcat线程池最少会有这么多线程。

比较容易弄混的是maxThreads和maxConnections这两个参数:

  1. maxThreads是指Tomcat线程池做多能起的线程数

  2. maxConnections则是Tomcat一瞬间做多能够处理的并发连接数。比如maxThreads=1000,maxConnections=800,假设某一瞬间的并发时1000,那么最终Tomcat的线程数将会是800,即同时处理800个请求,剩余200进入队列“排队”,如果acceptCount=100,那么有100个请求会被拒掉。

    注意:根据前面所说,只是并发那一瞬间Tomcat会起800个线程处理请求,但是稳定后,某一瞬间可能只有很少的线程处于RUNNABLE状态,大部分线程是TIMED_WAITING,如果你的应用处理时间够快的话。所以真正决定Tomcat最大可能达到的线程数是maxConnections这个参数和并发数,当并发数超过这个参数则请求会排队,这时响应的快慢就看你的程序性能了。

以上的结论都是我个人验证和总结,如有不对,跪求指正!!!

本文转载自:http://www.360doc.com/content/16/0726/14/35368984_578509236.shtml

jepacd
粉丝 5
博文 153
码字总数 210363
作品 0
朝阳
程序员
私信 提问
Tomcat的性能与最大并发(1000)

当一个进程有 500 个线程在跑的话,那性能已经是很低很低了。Tomcat 默认配置的最大请求数是 150,也就是说同时支持 150 个并发,当然了,也可以将其改大。 当某个应用拥有 250 个以上并发的...

搬砖小哥
2017/11/01
88
0
tomcat的性能与最大并发(1000)

当一个进程有 500 个线程在跑的话,那性能已经是很低很低了。Tomcat 默认配置的最大请求数是 150,也就是说同时支持 150 个并发,当然了,也可以将其改大。 当某个应用拥有 250 个以上并发的...

JasonO
2016/03/02
488
0
Tomcat性能优化

最近一直在解决线上一个问题,表现是: Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池满了,日志看很多请求超过了1s。 服务器性能很好,Tomcat版本是7.0...

voole
2016/08/06
256
0
tomcat6 高并发配置 与优化

tomcat的server.xml配置文件说明: server.xml配置 1. port="8080"protocol="HTTP/1.1" 2. maxThreads="30000" 3. minSpareThreads="512" 4. maxSpareThreads="2048" 5. enableLookups="fal......

凡尘网络
2016/01/07
331
0
异步非阻塞机制与多线程阻塞机制在处理并发耗时等待任务上的效率对比分析

应用服务器的性能分析是复杂的,关注点很多。比如典型场景Web服务器+数据库,底层网络链路和网络硬件性能姑且不论,单看:Web服务器对静态文件的读写与磁盘和文件系统IO性能紧密相关;对数据...

mallon
2014/04/20
2.6K
3

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 年迈渔夫遭黑帮袭抢

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享Elvis Presley的单曲《White Christmas》: 《White Christmas》- Elvis Presley 手机党少年们想听歌,请使劲...

小小编辑
今天
2.1K
20
CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
9
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
12
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
19
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部