如何决定Web应用的线程池大小
线程池(Thread Pool)
在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数。如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝。
请注意,并发和并行是不同的。并发请求是指在任何一个时间点,所有被处理的请求中只有只有很少一部分占用CPU(译者注:轮流使用CPU)。并行是指在任何一个时间点,所有被处理的请求同时在CPU上运行。
在非阻塞式(NO-Blocking)应用中(如NodeJs),一个单独的线程或进程可以并发处理多个请求。而在多核CPU中则可以通过增加线程或进程数来实现并行处理。
在阻塞式IO应用中(如java的SringMVC,一个线程只能同时处理一个并发请求。如果想要并发处理多个请求只能通过增加线程数来实现。
CPU消耗型应用
对于CPU消耗型应用来说,线程池的大小应该和单台服务器的CPU个数相同。对于这类应用由于线程上下文切换增加线程数反而会妨碍对请求的处理,同时还会增加响应时间。
非阻塞式IO应用由于在请求被处理时并不需要等待请求处理完成,因此属于CPU消耗型的应用。
IO消耗型应用
由于IO消耗型应用依赖于下行流量所在系统的响应时间,而且一个线程在其他系统响应完成之前将一直阻塞,所以决定IO消耗型应用的线程池大小变得更加困难。对于这类型应用,我们就像在阻塞式IO应用文章中讲的,通过增加线程数来提高CPU利用率。
科特尔法则(Little’s Law)
科特尔法则通常被用在非技术领域,例如告诉银行柜台出纳员还有多少客户在等待请求处理。
下面是维基百科对科特尔法的说明,英文原文如下:
The average number of threads in a system (Threads) is equal average web request arrival rate (WebRequests per sec), multiplied by the average response time (ResponseTime)
译文:一个系统的平均线程数(线程数)等于平均请求的到达率(每秒请求数)乘以平均响应时间(响应时间)。
公式:线程数=每秒请求数 X 响应时间
公式说明:
线程数系统所能处理的线程数量
每秒请求数每秒钟所能处理的请求数
响应时间处理一个请求所花费的时间
当然,上边的公式给出了处理多少请求需要多少线程,但是并没有考虑线程对CPU的占用率等情况,也没有说明对于多核的单台机器应该分配多少线程。
通过测试决定线程池大小
要分配合适大小的线程池就需要在吞吐量和响应时间这两个要素之间寻求平衡点。从每个CPU最少线程数开始(即线程数=cpu数),系统线程数和平均响应时间成正比直到CPU使用率达到最大或者响应时间不再减少为止。
下图说明了请求数、CPU和响应时间之间的关系。
CPU和请求数的图中展示了随着Web系统负载量不断增加时CPU的使用情况。
响应时间和请求数的图中展示了Web系统负载量的增加对响应时间的影响。
绿色的点表示吞吐量和响应时间的最优点。
线程池大小=CPU核心数

上图展示的是阻塞式IO消耗型应用在线程池大小等于CPU核心数量时的情况。线程由于要等待下行流量的IO处理所以会阻塞,而由于线程的阻塞使响应时间进一步增加,而且即使CPU的占用率非常低,但是线程池中所有线程都处于阻塞状态,那么应用还是会拒绝请求。
大的线程池
上图展示的是阻塞式IO消耗型应用在大的线程池下的使用情况。由于线城池数量大,线程上下文切换也变得非常频繁,而正是这些没必要的上下文切换使得应用还没有达到最大吞吐量时CPU就已经达到最大占用率了。请求响应时间也由于频繁的上下文切换而快速增长。
最优线程池大小

上图展示的是阻塞式IO消耗型应用在最优线程池下的情况。在高吞吐量和更少线程上文切换的情况下CPU得到了高效的利用。同时我们注意到,好的响应时间取决于在线程更少被阻断(上下文切换)的情况下对请求的高效处理。
线程池隔离
在大多数应用中,只有少数类型的请求会比其他请求更耗时,但这少数的耗时请求会影响整个系统的性能。有两个办法可以解决这个问题:
1)将比较耗时的请求隔离开来专门处理
2)在同一个应用中为耗时的web请求单独分配一个线程池
决定一个阻塞式IO消耗型应用的最优线程池大小是一件困难的事情,这通常需要通过多个性能测试来决定。如果在一个应用中使用多个线程池,会使对线程池的优化进一步复杂化。
如何决定Web应用的线程池大小的更多相关文章
- 如何决定 Web 应用的线程池大小
在部署 web 应用到生产环境,或者在对 web 应用进行性能测试的时候,经常会有人问:如何决定 web 应用线程池大小?决定一个 IO 阻塞型 web 应用的线程池大小是一项很艰巨的任务.通常是通过 ...
- 线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事
线程池应该设置多少线程合适,怎么样估算出来.最近接触到一些相关资料,现作如下总结. 最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊. 首先,需要考虑到线程池所 ...
- 如何计算tomcat线程池大小?
背景 在我们的日常开发中都涉及到使用tomcat做为服务器,但是我们该设置多大的线程池呢?以及根据什么原则来设计这个线程池呢? 接下来,我将介绍本人是怎么设计以及计算的. 目标 确定tomcat服务器 ...
- 发一个可伸缩线程池大小的python线程池。已通过测试。
发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...
- spring定时任务ThreadPoolTaskScheduler使用注意事项之线程池大小
背景 最近小伙伴解决了一个工单,描述为"手工推送案件无法推,提示token失效",当前工单状态为待关闭,解决方案为"东软接口不稳定造成的,东软的接口恢复正常后,问题解决& ...
- Java-如何合理的设置线程池大小
想要合理配置线程池线程数的大小,需要分析任务的类型,任务类型不同,线程池大小配置也不同. 配置线程池的大小可根据以下几个维度进行分析来配置合理的线程数: 任务性质可分为:CPU密集型任务,IO密集型任 ...
- ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别
工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍ThreadP ...
- hreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别
阅读更多 工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍Th ...
- 根据CPU核数合理设置线程池大小
一般来说池中总线程数是核心池线程数量两倍,只要确保当核心池有线程停止时,核心池外能有线程进入核心池即可. 我们所需要关心的主要是核心池线程的数量该如何设置. 自定义线程池代码 package com. ...
随机推荐
- 从 Python 第三方进度条库 tqdm 谈起 (转载)
原文地址: https://blog.ernest.me/post/python-progress-bar tqdm 最近一款新的进度条 tqdm 库比较热门,声称比老版的 python-progre ...
- OK335xS-Android pack-ubi-256M.sh hacking
#/******************************************************************************* # * OK335xS-Androi ...
- TJU Problem 1015 Gridland
最重要的是找规律. 下面是引用 http://blog.sina.com.cn/s/blog_4dc813b20100snyv.html 的讲解: 做这题时,千万不要被那个图给吓着了,其实这题就是道简 ...
- Cassandra 数据库, python cqlsh命令
★ cql操作数据库(cqlsh.bat: python cqlsh命令操作<优缺点:https://blog.csdn.net/vbirdbest/article/details/77662 ...
- python lambda匿名函数
Python的一个很重要的方面就是:函数式编程(functional programming),即可以再原本传递参数和值的地方传递函数. lambda x: x%3 == 0 和以下等价: def b ...
- $.each()与$(selector).each()
$.each()与$(selector).each()不同, 后者专用于jquery对象的遍历, 前者可用于遍历任何的集合(无论是数组或对象),如果是数组,回调函数每次传入数组的索引和对应的值(值亦可 ...
- hasura graphql server event trigger 试用
hasura graphql server 是一个很不错的graphql 引擎,当前版本已经支持event triiger 了 使用此功能我们可以方便的集成webhook功能,实现灵活,稳定,快捷的消 ...
- node express 返回json object
web 开发的过程中我们经常需要返回对象的json 格式,使用node express 是比较简单的, 1.node express 基础网站的创建 比较简单,以前的文章有 2.编写对象并导出对象 / ...
- 使用VBS发邮件
NameSpace = "http://schemas.microsoft.com/cdo/configuration/"set Email = CreateObject(&quo ...
- 什么是Asp.net Core?和 .net core有什么区别?(转)
什么是Asp.Net core 我相信很多C# Developer已经对于.net core不算陌生了,就算没有正式使用相信也应该有所了解.微软在推出来.net core的同时为了方便一些原有的项目可 ...