最近一直在解决线上一个问题,表现是:
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还有一个参数叫maxIdleTime:

其实从这个参数解释也能看出来Tomcat会停止闲置了超过一定时间的线程的,这个时间就是maxIdleTime。但我之前的测试中确实没有发现线程释放的现象,这是为什么呢?我发现除了这个参数线程池线程是否释放?释放多少?还跟当前Tomcat每秒处理的请求数(从Jmeter或LoadRunner来看可以理解为TPS)有关系。通过下表可以清晰的看出来线程数,TPS和maxIdleTime之间的关系:

TPS  maxIdleTime(ms) Thread Count
10 60,000 600
5 60,000 300
1 60,000

60

依次类推,当然Thread Count这一列是一个大约数,上下相差几个,但基本符合这样一个规则:

Thread Count = min(max((TPS * maxIdleTime)/1000,minSpareThreads),maxThreads)

当然这个Thread Count不会小于minSpareThreads,这个跟之前的结论还是一样的。我现在大胆猜测下(回头看源码验证下,或者哪位同学知道告诉我下,谢谢):

Tomcat线程池每次从队列头部取线程去处理请求,请求完结束后再放到队列尾部,也就是说前后两次请求处理不会用同一个线程。某个线程闲置超过maxIdleTime就释放掉。

假设首先线程池在高峰时期暴涨到1000,高峰过后Tomcat处理一次请求需要1s(从Jmeter看TPS大约就为1),那么在maxIdleTime默认的60s内会用到线程池中60个线程,那么最后理论上线程池会收缩到60(假设minSpareThreads大于60)。另外:这个跟用不用Keep-Alive没关系(之前测试结论是因为用了Keep-Alive导致程序性能下降,TPS降低了很多导致的)

这就是为什么我之前的测试中、还有我们生产环境中线程数只增不减的原因,因为就算峰值过后我们的业务每秒请求次数仍然有100多,100*60=6000,也就是3000个线程每个线程在被回收之前肯定会被重用。

那么现在有另外一个问题,那么正常情况下为什么每秒100次的请求不会导致线程数暴增呢?也就是说线程暴增到3000的瓶颈到底在哪?这个我上面的结论其实也不是很准确。

真正决定Tomcat最大可能达到的线程数是maxConnections这个参数和并发数,当并发数超过这个参数则请求会排队,这时响应的快慢就看你的程序性能了。

这里没说清楚的是并发的概念,不管什么并发肯定是有一个时间单位的(一般是1s),准确的来讲应该是当时Tomcat处理一个请求的时间内并发数,比如当时Tomcat处理某一个请求花费了1s,那么如果这1s过来的请求数达到了3000,那么Tomcat的线程数就会为3000,maxConnections只是Tomcat做的一个限制。

2、为什么线程池会满?

这是我现在纠结的核心。到底是不是应用的性能慢导致的,我现在的结论是有关系,但关键是并发。

Tomcat的线程池的线程数跟你的瞬间并发有关系,比如maxThreads设置为1000,当瞬间并发达到1000那么Tomcat就会起1000个线程来处理,这时候跟你应用的快慢关系不大。
那么是不是并发多少Tomcat就会起多少个线程呢?这里还跟Tomcat的这几个参数设置有关系,看官方的解释是最靠谱的:

我简单理解就是: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这个参数和并发数,当并发数超过这个参数则请求会排队,这时响应的快慢就看你的程序性能了。

往期精彩内容:

Java知识体系总结(2021版)

Java多线程基础知识总结(绝对经典)

超详细的springBoot学习笔记

常见数据结构与算法整理总结

Java设计模式:23种设计模式全面解析(超级详细)

Java面试题总结(附答案)

原创不易,转载自:https://blog.csdn.net/hunhun1122/article/details/78818337

tomcat优化——并发和Tomcat线程数相关推荐

  1. tomcat如何增大并发_tomcat最大线程数,单台tomcat最大并发量

    tomcat最大线程数,单台tomcat最大并发量,tomcat最大线程数的设置 Connector port="8080" maxThreads="150"  ...

  2. SpringBoot中修改tomcat最大连接数、最大线程数、最大等待数

    1)maxThreads(最大线程数)每一次HTTP请求到达Web服务器,Web服务器都会创建一个线程来处理该请求,该参数决定了应用服务同时可以处理多少个HTTP请求,tomcat默认为200:2)a ...

  3. 性能测试:深入理解并发量,线程数,吞吐量,TPS

    并发数,线程数,吞吐量,每秒事务数(TPS)都是性能测试领域非常关键的数据和指标. 那么他们之间究竟是怎样的一个对应关系和内在联系? 测试时,我们经常容易将线程数等同于表述为并发数,这一表述正确吗? ...

  4. tomcat线程释放时间_聊下并发和Tomcat线程数(错误更正)

    本文前半部分结论存在严重错误,请看最后2015-1-20更新部分. 最近一直在解决线上一个问题,表现是: Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池 ...

  5. 聊下并发和Tomcat线程数(Updated)

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

  6. 聊下并发和Tomcat线程数(错误更正)

    本文前半部分结论存在严重错误,请看最后2015-1-20更新部分. 最近一直在解决线上一个问题,表现是: Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池 ...

  7. SpringBoot 内置 Tomcat 线程数优化配置,你学会了吗?

    前言 本文解析springboot内置tomcat调优并发线程数的一些参数,并结合源码进行分析 参数 线程池核心线程数 server.tomcat.min-spare-threads:该参数为tomc ...

  8. windows查看tomcat连接数_Springboot内置Tomcat线程数优化

    # 等待队列长度,默认100.队列也做缓冲池用,但也不能无限长,不但消耗内存,而且出队入队也消耗CPU server.tomcat.accept-count=1000 # 最大工作线程数,默认200. ...

  9. tomcat高并发与优化

    tomcat的server.xml配置文件说明: server.xml配置 <Connectorport="8080"protocol="HTTP/1.1" ...

最新文章

  1. BST AVL 红黑树 B B+树
  2. lvs系列之dr(二)
  3. 从阿里核心场景看实时数仓的发展趋势
  4. .html好 还是.asp好,各位说说在ASP.net里 用静态函数的好 还是实例函数出处HTML好???...
  5. antimalware可以关闭吗_EMUI这几个功能一定要关闭 不然手机会越来越卡
  6. LeetCode - 7 - Reverse Integer
  7. 华为云GuassDB(for Redis)发布全新版本推出:Lua脚本和SSL连接加密
  8. oracle中日期相减及显示几天几小时几分钟
  9. linux中的页缓存和文件IO
  10. 高级珠宝Cartier
  11. Win7下安装Mysql5.7.26
  12. 三维建筑动画的制作流程
  13. 使用单视点模型进行水下标定的分析
  14. 在微控制器平台等小型物联网设备上运行 JavaScript
  15. 做期货能不能尽量不止损?
  16. 爬虫学习:基础爬虫案例实战
  17. Android反编译:手把手教你制作高德地图车机共存版
  18. 鸡啄米:C++编程入门系列之五(运算符和表达式)
  19. uniApp APP跳转支付宝小程序,uniapp唤起支付小程序
  20. 《HarmonyOS开发 - IPC Camera开发笔记》第2章 HiSpark IPC Camera开发环境搭建(基于V1.1.4)

热门文章

  1. Oracle函数总结(含举例)持续更新
  2. java 商品多规格_大家有做过商品多规格的功能嘛?商品的不同规格对应不同价格和库存一般是如何实现的?...
  3. WebView播放Swf文件
  4. js连接web3,连接小狐狸metamask钱包,实现链不对后切换网络和创建网络
  5. win7 win8下 dvorak 的安装和练习
  6. 2021 vivo校招提前批笔试解析
  7. 【WLAN】【软件】NXP芯片方案用户态和内核态通讯方式小结
  8. [ Linux驱动炼成记 ] 15 - 存储器EMMC中Ext4文件系统 中 磁盘空间占用率100%
  9. html排版标记应用,HTML的排版标记_html
  10. GitHub上 7 个Spring Boot 优质开源项目