tomcat调优

image.png

线程池大小 = 每秒请求数 × 平均请求处理时间

假设服务器是单核的:

线程池大小 = (线程 I/O 阻塞时间 + 线程 CPU 时间 )/ 线程 CPU 时间
其中:线程 I/O 阻塞时间 + 线程 CPU 时间 = 平均请求处理时间

对比一下两个公式,你会发现,平均请求处理时间在两个公式里都出现了,这说明请求时间越长,需要更多的线程是毫无疑问的。
不同的是第一个公式是用每秒请求数来乘以请求处理时间;而第二个公式用请求处理时间来除以线程 CPU 时间,请注意 CPU 时间是小于请求处理时间的
虽然这两个公式是从不同的角度来看待问题的,但都是理想情况,都有一定的前提条件。

  1. 请求处理时间越长,需要的线程数越多,但前提是 CPU 核数要足够,如果一个 CPU 来支撑 10000 TPS 并发,创建 10000 个线程,显然不合理,会造成大量线程上下文切换。
  2. 请求处理过程中,I/O 等待时间越长,需要的线程数越多,前提是 CUP 时间和 I/O 时间的比率要计算的足够准确。
  3. 请求进来的速率越快,需要的线程数越多,前提是 CPU 核数也要跟上。

实际场景下如何确定线程数

  • 那么在实际情况下,线程池的个数如何确定呢?这是一个迭代的过程,先用上面两个公式大概算出理想的线程数,再反复压测调整,从而达到最优
  • 一般来说,如果系统的 TPS 要求足够大,用第一个公式算出来的线程数往往会比公式二算出来的要大。我建议选取这两个值中间更靠近公式二的值。也就是先设置一个较小的线程数,然后进行压测,当达到系统极限时(错误数增加,或者响应时间大幅增加),再逐步加大线程数,当增加到某个值,再增加线程数也无济于事,甚至 TPS 反而下降,那这个值可以认为是最佳线程数。
  • 线程池中其他的参数,最好就用默认值,能不改就不改,除非在压测的过程发现了瓶颈。如果发现了问题就需要调整,比如 maxQueueSize,如果大量任务来不及处理都堆积在 maxQueueSize 中,会导致内存耗尽,这个时候就需要给 maxQueueSize 设一个限制。当然,这是一个比较极端的情况了。
    再比如 minSpareThreads 参数,默认是 25 个线程,如果你发现系统在闲的时候用不到 25 个线程,就可以调小一点;如果系统在大部分时间都比较忙,线程池中的线程总是远远多于 25 个,这个时候你就可以把这个参数调大一点,因为这样线程池就不需要反复地创建和销毁线程了。

总结

  • 今天学习了 I/O 调优,也就是如何选择连接器的类型,以及在选择过程中有哪些需要注意的地方。
  • 后面还聊到 Tomcat 线程池的各种参数,其中最重要的参数是最大线程数 maxThreads。理论上我们可以通过利特尔法则或者 CPU 时间与 I/O 时间的比率,计算出一个理想值,这个值只具有指导意义,因为它受到各种资源的限制,实际场景中,我们需要在理想值的基础上进行压测,来获得最佳线程数。

<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
connectionTimeout="30000"
URIEncoding="UTF-8"
minSpareThreads="100"
maxThreads="4096"
acceptCount="10000"
enableLookups="false"
disableUploadTimeout="true"
redirectPort="8443" />

  • org.apache.coyote.http11.Http11Nio2Protocol
    在tomcat8中有最新的nio2,速度更快,也建议使用nio2,nio2连接器需要tomcat8.0以上才有
  • connectionTimeout
    网络超时时间,单位:毫秒,设置为 0 表示永不超时,这样设置有隐患的。通常可设置为 30000 毫秒,可根据检测实际情况,适当修改
  • URIEncoding:tomcat容器编码配置
  • maxThreads : tomcat处理请求是是用的线程来处理的,这个表示tomcat的最大线程数,默认200(maxThreads='5000' 最大可以处理5000发并发请求 nginx一般可以达到5w)
  • minSpareThreads:最小空闲线程数,表示没人访问的时候,也开多少线程等待访问(最小要启动的线程数去处理用户的请求,这个随着用户的请求是不断增加的)
  • acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为100个。
  • enableLookups:反查域名,true返回远程主机的主机名,false返回ip地址,为了提高处理能力,应设置为 false(Tomcat接收用户请求根据用户的IP去反查用户的主机名,相当于查找DNS,这样做没有意义的 主要是为了安全,看看用户ip可不可以解析出域名,这个消耗时间 ,这个要关闭)
  • disableUploadTimeout="true" 禁止上传超时,上传时是否使用超时机制

tomcat中maxConnections、maxThreads、acceptCount的具体含义

比较容易弄混的是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这个参数和并发数,当并发数超过这个参数则请求会排队,这时响应的快慢就看你的程序性能了

一、accept-count:最大等待数

官方文档的说明为:当所有的请求处理线程都在使用时,所能接收的连接请求的队列的最大长度。当队列已满时,任何的连接请求都将被拒绝。accept-count的默认值为100。
详细的来说:当调用HTTP请求数达到tomcat的最大线程数时,还有新的HTTP请求到来,这时tomcat会将该请求放在等待队列中,这个acceptCount就是指能够接受的最大等待数,默认100。如果等待队列也被放满了,这个时候再来新的请求就会被tomcat拒绝(connection refused)。

二、maxThreads:最大线程数(线程池中最大允许容纳的线程数量)

每一次HTTP请求到达Web服务,tomcat都会创建一个线程来处理该请求,那么最大线程数决定了Web服务容器可以同时处理多少个请求。maxThreads默认200,肯定建议增加。但是,增加线程是有成本的,更多的线程,不仅仅会带来更多的线程上下文切换成本,而且意味着带来更多的内存消耗。JVM中默认情况下在创建新线程时会分配大小为1M的线程栈,所以,更多的线程异味着需要更多的内存。线程数的经验值为:1核2g内存为200,线程数经验值200;4核8g内存,线程数经验值800。

三、maxConnections:最大连接数(BIO默认为maxThreads的值,NIO默认为10000)

官方文档的说明为:
这个参数是指在同一时间,tomcat能够接受的最大连接数。对于Java的阻塞式BIO,默认值是maxthreads的值;如果在BIO模式使用定制的Executor执行器,默认值将是执行器中maxthreads的值。对于Java 新的NIO模式,maxConnections 默认值是10000。
对于windows上APR/native IO模式,maxConnections默认值为8192,这是出于性能原因,如果配置的值不是1024的倍数,maxConnections 的实际值将减少到1024的最大倍数。
如果设置为-1,则禁用maxconnections功能,表示不限制tomcat容器的连接数。
maxConnections和accept-count的关系为:当连接数达到最大值maxConnections后,系统会继续接收连接,但不会超过acceptCount的值。

图解:maxConnections、maxThreads、acceptCount关系

用一个形象的比喻,通俗易懂的解释一下tomcat的最大线程数(maxThreads)、最大等待数(acceptCount)和最大连接数(maxConnections)三者之间的关系。

我们可以把tomcat比做一个火锅店,流程是取号、入座、叫服务员,可以做一下三个形象的类比:
(1)acceptCount 最大等待数
可以类比为火锅店的排号处能够容纳排号的最大数量;排号的数量不是无限制的,火锅店的排号到了一定数据量之后,服务往往会说:已经客满。
(2)maxConnections 最大连接数
可以类比为火锅店的大堂的餐桌数量,也就是可以就餐的桌数。如果所有的桌子都已经坐满,则表示餐厅已满,已经达到了服务的数量上线,不能再有顾客进入餐厅了。
(3)maxThreads:最大线程数
可以类比为厨师的个数。每一个厨师,在同一时刻,只能给一张餐桌炒菜,就像极了JVM中的一条线程。

整个就餐的流程,大致如下:

(1)取号:如果maxConnections连接数没有满,就不需要取号,因为还有空余的餐桌,直接被大堂服务员领上餐桌,点菜就餐即可。如果 maxConnections 连接数满了,但是取号人数没有达到 acceptCount,则取号成功。如果取号人数已达到acceptCount,则拿号失败,会得到Tomcat的Connection refused connect 的回复信息。
(2)上桌:如果有餐桌空出来了,表示maxConnections连接数没有满,排队的人,可以进入大堂上桌就餐。
(3)就餐:就餐需要厨师炒菜。厨师的数量,比顾客的数量,肯定会少一些。一个厨师一定需要给多张餐桌炒菜,如果就餐的人越多,厨师也会忙不过来。这时候就可以增加厨师,一增加到上限maxThreads的值,如果还是不够,只能是拖慢每一张餐桌的上菜速度,这种情况,就是大家常见的“上一道菜吃光了,下一道菜还没有上”尴尬场景。

maxConnections、maxThreads、acceptCount关系图如下

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Tomcat可以从内存、并发、缓存等方面进行优化 1、Tomcat内存优化: 在tomcat的启动脚本catali...
    心云间丶聆听阅读 1,589评论 0 7
  • 一、JVM 参数作用建议-server以服务端的模式运行建议开启-Xms最小堆内存,和-Xmx设置相同-Xmx最大...
    白璞1024阅读 153评论 0 0
  • /bin/catalina.battomcat调高最大内存为1024M,解决内存溢出;set JAVA_OPTS=...
    咖啡机an阅读 550评论 0 0
  • jdk8和Tomcat8.5是JDK和Tomcat的史诗级提升,直接把单车变跑车,所以如果你还是使用的jdk7和T...
    笔记本一号阅读 1,255评论 0 3
  • tomcat的配置相关参数:1)ConnectionTimeout: 默认20s,其实就是tomcat的一种保护机...
    瓢鳍小虾虎阅读 218评论 0 0