线程池(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应用的线程池大小的更多相关文章

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

    在部署 web 应用到生产环境,或者在对 web 应用进行性能测试的时候,经常会有人问:如何决定 web 应用线程池大小?决定一个 IO 阻塞型 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. matlab mod()&rem()

    一.介绍rem/mod(X,Y)当X,Y符号相同的时候,这两者一样,当符号不相同的时候才有差别,具体表现在rem结果的符号与被除数相同:mod结果的符号与除数相同 二.例子 >> a=9; ...

  2. opencv-python教程学习系列13-图像平滑

    前言 opencv-python教程学习系列记录学习python-opencv过程的点滴,本文主要介绍图像平滑,坚持学习,共同进步. 系列教程参照OpenCV-Python中文教程: 系统环境 系统: ...

  3. Adobe Flash Player - imsoft.cnblogs

    Adobe Flash Player是一个跨平台.基于浏览器的应用程序.运行时,它可以跨屏幕和浏览器原汁原味地查看具有表现力的应用程序.内容和视频.Flash Player实现了移动屏幕上的高性能优化 ...

  4. Springboot集成mybatis(mysql),mail,mongodb,cassandra,scheduler,redis,kafka,shiro,websocket

    https://blog.csdn.net/a123demi/article/details/78234023  : Springboot集成mybatis(mysql),mail,mongodb,c ...

  5. LG3898 [湖南集训]大新闻

    题意 题目描述 **记者弄了个大新闻,这个新闻是一个在 [0,n) 内等概率随机选择的整数,记其为 x.为了尽可能消除这个大新闻对公众造成的不良印象,我们需要在 [0,n)内找到某一个整数 y,使得 ...

  6. UVa 10410 树重建

    Tree Reconstruction Problem Description You have just finished a compiler design homework question w ...

  7. ballerina 学习 三十一 扩展开发(二)

    上篇说了使用ballerina 语言开发扩展模块,对于注解类型的我们是需要使用java 语言进行 开发的 官方提供了一个hello 的demo可以参考 https://github.com/balle ...

  8. SQL Support and Workarounds

    此文章来自官方文档,说明了,对于不支持pg 标准的sql 查询的变通方法,实际使用的时候有很大的指导意义 As Citus provides distributed functionality by ...

  9. sql 变量赋值

    mysql 的变量赋值如下: set @name='app' ; or set @name:='appfirst'; or with select select @appname:='you name ...

  10. fork 开源项目后如何参与项目

    好的开源项目都很想参与到开源活动中,并且会 fork 一份. 经过几个月的学习,大概明白了如果参与开源项目. 当完成 fork 后,就需要在本地 git clone 一份. 有新的功能或需要修复的就开 ...