在部署 web 应用到生产环境,或者在对 web 应用进行性能测试的时候,经常会有人问:如何决定 web 应用线程池大小?决定一个 IO 阻塞型 web 应用的线程池大小是一项很艰巨的任务。通常是通过进行大量的性能测试来完成。在一个 web 应用中同时拥有多个线程池会让决定最优线程池大小的过程变得更加复杂。本文将就这个常见的问题进行一些讨论和建议。

线程池

web 应用中的线程池大小决定了在指定时间内能够处理的并发请求数。如果一个 web 应用接收到的请求数高于线程池大小,多出来的请求将进入队列等待,或被拒绝。

请注意并发和并行不是一个概念。并发请求指的是正在处理中的请求数量,在某个时间点,只有其中的一小部分能够得到 CPU 执行。而并行请求指的是正在处理的请求数量,在某个时间点,所有请求都在被 CPU 执行。

在非阻塞型 IO 应用中,比如 NodeJS,单个线程(进程)能够同时处理多个请求。多核 CPU 处理器下,通过增加线程或进程数能够处理并行请求。

在阻塞型 IO 应用中,比如 SpringMVC,单个线程只能同时处理一个请求。要同时处理多个并发请求的话,我们必须增加线程数量。

计算密集型应用

在计算密集型应用中,线程池的大小应该等同于主机中 CPU 的数量。再添加更多线程将会打断请求的处理,因为线程的上下文切换也会延迟响应时间。

非阻塞型 IO 应用将会是 CPU 密集型的,因为在请求得到处理的时候没有线程等待时间。

IO 等待应用

决定 IO 等待应用的线程池大小会由于依赖于下游系统的响应时间而变得更加复杂,因为一个线程在其他系统响应之前始终是阻塞的。我们不得不像《应答者模式:I/O 阻塞型应用》中讨论的那样去增加线程的数量以提高 CPU 利用率。

利特尔法则

利特尔法则应用于非技术领域,比如银行,以估算处理进入银行客户所需要的银行出纳柜台的数量。

利特尔法则:在一个稳定的系统中,长时间观察到的平均顾客数量 L,等于长时间观察到的有效到达速率,λ,与平均每个顾客在系统中花费的时间之乘积:L = λW。

适用于 web 应用的利特尔法则:一个系统中线程的平均数量(Threads),等于 web 请求的到达速率(WebRequests per sec),与平均每个处理的响应时间(ResponseTime)的乘积。

Threads = 线程的数量

WebRequests per sec = 一秒内能够处理的 web 请求数

ResponseTime = 处理一次 web 请求所需要的时间

Threads = (WebRequests/sec) X ResponseTime

尽管上边这个公式提供了处理进入请求的线程个数,它并没有提供线程数和 CPU 核心数之间的比率信息,比如一个 x 个 CPU 的主机需要分配多少个线程。

测试决定线程池大小

要找出合适的线程池大小,需要在吞吐量和响应时间之间进行权衡。先以一个最小值开始测试:一个 CPU 一个线程(也就是线程池大小 = CPU 个数),应用线程池大小与下游系统平均响应时间成正比增长,直到 CPU 使用率饱和或者响应时间开始退化为止。

下图指出了请求数、CPU 以及响应时间等指标之间的关联关系。

CPU Vs 请求数演示了在增加 web 应用负载时的 CPU 利用率。

响应时间 Vs 请求数图演示了增加 web 应用负载对响应时间的影响。

绿点指出了最佳吞吐量和响应时间。

线程池大小 = CPU 个数



上图描述的是 IO 等待型应用在线程数等于 CPU 数时的情况。应用的线程在等待下游系统响应时发生了阻塞。由于线程都阻塞住了,系统响应时间因请求进入等待队列而被拉长。由于所有线程都处于阻塞状态,应用开始拒绝请求,尽管 CPU 使用率还很低。

线程池很大



上图描述的是 IO 等待型应用在 web 应用中创建了很多线程的情况。由于有很多数量的线程,线程的上下文切换将会很频繁。由于不必要的线程上下文切换,尽管吞吐量还没升上去的时候应用的 CPU 使用率就已经很高了。响应时间由于被请求的处理被线程的上下文切换所打断而被拉长。

最佳线程池大小



上图描述的是 IO 等待型应用在 web 应用中创建了合理数量的线程的情况。CPU 得到了有效利用,具备良好的吞吐量和较少的线程上下文切换。我们可以看到由于更少的打断(上下文切换),请求处理更加有效,应用有一个良好的响应时间。

线程池隔离

对于大多数 web 应用而言,只有少数几种类型的 web 请求会花费比较长的处理时间。这些慢的请求处理可能会拖累所有线程,并降低整个应用的性能。

处理这种问题的两个方案是:

为慢处理的 web 请求设置在一台独立的主机;

在同一个应用中为慢处理的 web 请求分配一个独立的线程池;

决定一个 IO 阻塞型 web 应用的线程池大小是一项很艰巨的任务。通常是通过进行大量的性能测试来完成。在一个 web 应用中同时拥有多个线程池会让决定最优线程池大小的过程变得更加复杂。

原文链接:http://venkateshcm.com/2014/05/How-To-Determine-Web-Applications-Thread-Poll-Size/。

如何决定 Web 应用的线程池大小的更多相关文章

  1. 如何决定Web应用的线程池大小

    线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...

  2. 线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事

    线程池应该设置多少线程合适,怎么样估算出来.最近接触到一些相关资料,现作如下总结. 最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊. 首先,需要考虑到线程池所 ...

  3. 如何计算tomcat线程池大小?

    背景 在我们的日常开发中都涉及到使用tomcat做为服务器,但是我们该设置多大的线程池呢?以及根据什么原则来设计这个线程池呢? 接下来,我将介绍本人是怎么设计以及计算的. 目标 确定tomcat服务器 ...

  4. 发一个可伸缩线程池大小的python线程池。已通过测试。

    发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...

  5. spring定时任务ThreadPoolTaskScheduler使用注意事项之线程池大小

    背景 最近小伙伴解决了一个工单,描述为"手工推送案件无法推,提示token失效",当前工单状态为待关闭,解决方案为"东软接口不稳定造成的,东软的接口恢复正常后,问题解决& ...

  6. Java-如何合理的设置线程池大小

    想要合理配置线程池线程数的大小,需要分析任务的类型,任务类型不同,线程池大小配置也不同. 配置线程池的大小可根据以下几个维度进行分析来配置合理的线程数: 任务性质可分为:CPU密集型任务,IO密集型任 ...

  7. ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别

    工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍ThreadP ...

  8. hreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别

    阅读更多 工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍Th ...

  9. 根据CPU核数合理设置线程池大小

    一般来说池中总线程数是核心池线程数量两倍,只要确保当核心池有线程停止时,核心池外能有线程进入核心池即可. 我们所需要关心的主要是核心池线程的数量该如何设置. 自定义线程池代码 package com. ...

随机推荐

  1. 第二周的java

  2. MFC 屏蔽esc跟enter键

    BOOL CMenuOperate::PreTranslateMessage(MSG* pMsg) { if(pMsg->message == WM_KEYDOWN && pMs ...

  3. 21 ~ express ~ 内容详情展示 和 阅读数处理

    1,前台 ,/views/main/index.html ,将文章 id 通过url 传送给后台 {% for content in contents %} <div class="p ...

  4. QF中间件

    QF中间件使用说明          QF中间件是在2020年春节期间出现新型冠状病毒感染的肺炎疫情不敢外出,闲来无事编写的.编程是业余爱好,平时编程只会拖控件,中间件可能存在未知Bug,这个版本也只 ...

  5. Transaction Managament(事务管理二、Spring事务)

    Transaction Managament(事务管理二.Spring事务) Spring事务框架的优势 ​ Spring事务框架将开放过程中事务管理相关的关注点进行了分离,对这些关注点进行了抽象分离 ...

  6. MD5碰撞和MD5值(哈希值)相等

    md5的碰撞 0e开头的md5和原值: s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974 ...

  7. web网页外部分享到微信、朋友圈、扣扣、微博等功能、自动生成二维码等

    1.这里重中之重是分享到微信:web端网页通常是没有权限分享过去的 所以用: weixin://dl/business/?ticket=ta428dhj739hg3efe6e  但是这个ticket真 ...

  8. PAT 2018 春

    A 1140 Look-and-say Sequence 简单模拟.可能要注意字符串第一个字符和最后一个字符的处理. #include <cstdio> #include <iost ...

  9. [CISCN2019 总决赛 Day2 Web1]Easyweb

    0x00 知识点 1:备份文件泄露 2:SQL注入 3:php短标签 短标签<? ?>需要php.ini开启short_open_tag = On,但<?= ?>不受该条控制. ...

  10. eclipse上部署到tomcat不能自动部署maven管理的额jar包