• CHEN川
    2019-03-21
    更多的精力其实应该放在算法的优化上,线程池的配置,按照经验配置一个,随时关注线程池大小对程序的影响即可,具体做法:可以为你的程序配置一个全局的线程池,需要异步执行的任务,扔到这个全局线程池处理,线程池大小按照经验设置,每隔一段时间打印一下线程池的利用率,做到心里有数。

    看到过太多的代码,遇到要执行一个异步任务就创建一个线程池,导致整个程序的线程池大到爆,完全没必要。而且大多数时候,提高吞吐量可以通过使用缓存、优化业务逻辑、提前计算好等方式来处理,真没有必要太过于关注线程池大小怎么配置,如果小了就改大一点,大了改小一点就好,从老师本文的篇幅也可以看出来。

    经验值不靠谱的另外一个原因,大多数情况下,一台服务器跑了很多程序,每个程序都有自己的线程池,那CPU如何分配?还是根据实际情况来确定比较好。
    展开
     5
     78
  • 假行僧
    2019-03-21
    个人觉得公式话性能问题有些不妥,定性的io密集或者cpu密集很难在定量的维度上反应出性能瓶颈,而且公式上忽略了线程数增加带来的cpu消耗,性能优化还是要定量比较好,这样不会盲目,比如io已经成为了瓶颈,增加线程或许带来不了性能提升,这个时候是不是可以考虑用cpu换取带宽,压缩数据,或者逻辑上少发送一些。最后一个问题,我的答案是大部分应用环境是合理的,老师也说了是积累了一些调优经验后给出的方案,没有特殊需求,初始值我会选大家都在用伪标准

    作者回复: 👍👍

     1
     23
  • 多拉格·five
    2019-03-21
    问一下老师,这个线程配置比我在其他的资料也看过,但是最后那个公式没见过,方便说一下如何测试IO/CPU 这个耗时比例吗

    作者回复: 比较简单的工具就是apm了

    
     23
  • 不靠谱的琴谱
    2019-03-21
    如果我一个cpu是4核8线程 这里线程数数量是4+1还是8+1(cpu密集类型)
     5
     16
  • aksonic
    2019-03-21
    早起的鸟果然有食吃,抢到了顶楼,哈哈。
    对于老师的思考题,我觉得不合理,本来就是分CPU密集型和IO密集型的,尤其是IO密集型更是需要进行测试和分析而得到结果,差别很大,比如IO/CPU的比率很大,比如10倍,2核,较佳配置:2*(1+10)=22个线程,而2*CPU核数+1 = 5,这两个差别就很大了。老师,我说的对不对?

    作者回复: 不但起的早,还看懂了

    
     14
  • 董宗磊
    2019-03-21
    思考题:认为不合理,不能只考虑经验,还有根据是IO密集型或者是CPU密集型,具体问题具体分析。
    看今天文章内容,分享个实际问题;我们公司服务器都是容器,一个物理机分出好多容器,有个哥们设置线程池数量直接就是:Runtime.getRuntime().availableProcessors() * 2;本来想获取容器的CPU数量 * 2,其实Runtime.getRuntime().availableProcessors()获取到的是物理机CPU合数,一下开启了好多线程 ^_^

    作者回复: 新版的jvm开始支持docker了,老版本问题还挺多

    
     12
  • 探索无止境
    2019-03-21
    老师早上好,当应用来的请数量过大,此时线程池的线程已经不够使用,排队的队列也已经满了,那么后面的请求就会被丢弃掉,如果这是一个更新数据的请求操作,那么就会出现数据更新丢失,老师有没有什么具体的解决思路?期待解答

    作者回复: 单机有瓶颈,就分布式。
    数据库有瓶颈,就分库分表分片

     1
     11
  • 南山
    2019-03-31
    理论加经验加实际场景,比如现在大多数公司的系统是以服务的形式来通过docker部署的,每个docker服务其实对应部署的就一个服务,这样的情况下是可以按照理论为基础,再加上实际情况来设置线程池大小的,当然通过各种监控来调整是最好的,但是实际情况是但服务几十上百,除非是核心功能,否则很难通过监控指标来调整线程池大小。理论加经验起码不会让设置跑偏太多,还有就是服务中的各种线程池统一管理是很有必要的

    作者回复: 说的太对了!!!

    
     7
  • 榣山樵客™
    2019-03-22
    在4核8线程的处理器使用Runtime.availableProcessors()结果是8,超线程技术属于硬件层面上的并发,从cpu硬件来看是一个物理核心有两个逻辑核心,但因为缓存、执行资源等存在共享和竞争,所以两个核心并不能并行工作。超线程技术统计性能提升大概是30%左右,并不是100%。另外,不管设置成4还是8,现代操作系统层面的调度应该是按逻辑核心数,也就是8来调度的(除非禁用超线程技术)。所以我觉得这种情况下,严格来说,4和8都不一定是合适的,具体情况还是要根据应用性能和资源的使用情况进行调整。这是个人的理解,请老师指正。

    作者回复: 工作中都是按照逻辑核数来的,理论值和经验值只是提供个指导,实际上还是要靠压测。

    
     5
  • QQ怪
    2019-03-21
    我就想问下如何测试io耗时和cpu耗时

    作者回复: apm工具可以

    
     4
  • 已忘二
    2019-03-21
    老师,有个疑问,就是那个I/O和CPU比为2:1时,CPU使用率达到了100%,但是I/O使用率却到了200%,也就是时刻有两个I/O同时执行,这样是可以的么?I/O不需要等待的么?

    作者回复: io有瓶颈后,cpu使用率就上不去了

     1
     4
  • zsh0103
    2019-03-21
    请问老师,
    1 在现实项目如何计算I/O耗时与CPU耗时呢,比如程序是读取网络数据,然后分析,最后插入数据库。这里网络读取何数据库插入是两次IO操作,计算IO耗时是两次的和吗?
    2. 如果我在一台机器上部署2个服务,那计算线程数是要每个服务各占一半的数量吗?
    3. 如果我用一个8核CPU的机器部署服务,启动8个不同端口的相同服务,和启动一个包含8个线程的服务在处理性能上会有区别吗?

    作者回复: 1.两次之和
    2.理论值仅仅适用部署一个服务的场景。
    3.有区别

    
     4
  • 阿冲
    2019-03-21
    老师,你好!有个疑惑就是我在写web应用的时候一般都是一个请求里既包含cpu计算(比如字符串检验)又包含操作(比如数据库操作),这种操作就是一个线程完成的。那么这种情况按你写的这个公式还起作用吗?c#里面有对io操作基本都封装了异步方法,很容易解决我刚说的问题(调用异步方法就会切换线程进行io操作,等操作完了再切回来)。java要达到这种效果代码一般怎么写比较合适?

    作者回复: 就是针对一个线程既有cpu也有io的,这个才是io密集型

     1
     4
  • Weixiao
    2019-03-24
    最佳线程数 =1 +(I/O 耗时 / CPU 耗时),

    文中说,1表示一个线程执行io,另外R个线程刚好执行完cpu计算。

    这里理解有点问题,这个公式是按照单核给出的,所以不可能存在同时R个线程执行cpu计算。所以我理解文章中说反了,应该是1个线程在执行cpu,然后有R个线程可以同时在执行io,这样cpu的利用率为100%
    展开

    作者回复: 你对照着图理解一下,cpu时间上没有重叠

     1
     3
  • dingdongfm
    2019-09-24
    非常赞的一篇分享,可以结合https://time.geekbang.org/column/article/40742看。虽然两篇文章描述不太一致,但是不影响理解消化。
    
     2
  • Geek_Zjy
    2019-07-19
    我有个疑惑哈,老师的算法都是以 CPU 核数为参数,但是在硬件上有这种情况:
    比如Intel 赛扬G460是单核心,双线程的CPU,
    Intel 酷睿i3 3220是双核心 四线程,
    Intel 酷睿i5 4570是四核心 四线程,
    Intel 酷睿i7 4770K是四核心 八线程 等等
    这个对那个算法有影响吗?
    还有就是线程让出CPU内核 时,他的数据是要刷新到内存中保存吗?(我不是想要挑刺啊,我是觉得这个和前面讲的可见性应该有关系,比如单核多线程是不是不会有可见性的问题?当然只要是单线程不管多少核则定没有可见性的问题)
    @董宗磊 提到了 availableProcessors ,这个我看文档写的是获得可用的Java虚拟机的可用的处理器数量,和实际的主机 CPU 核数不是一致的吧,先忽略 docker 的问题,它可以用作算法中的 CPU核数吗?(我对“可用”俩字也很迷惑,难道这个数量会动态变化吗?)
    展开

    作者回复: 用逻辑核数就行,也就是操作系统里看到的核数

    
     2
  • 机遇号
    2019-03-22
    实际项目中怎么确定IO耗时、CPU耗时?

    作者回复: apm工具可以精确到方法耗时,io相关的方法一般是知道的

    
     2
  • 曾轼麟
    2019-03-22
    老师我记得csapp那本书中说过,x86架构的CPU是拥有超程技术的,也就是一个核可以当成两个使用,AMD的却没有,不知道您的这个计算公式是否适合其它厂商的CPU呢?

    作者回复: 都按照逻辑核数设置,最终还是要根据压测数据调整的

    
     2
  • 狂战俄洛伊
    2019-03-21
    对于这个思考题,我觉得是比较合理。
    因为经验是经过大量实践的结果,是符合大多数的情况,而且是一种快速估计的方法。
    我看留言区里很多都说不合理,并且给出了例子。我觉得他们说的也没错,只是举出了经验没覆盖到的情况而已。
    这里我还有个疑问,这篇文章中都是在讲一台机器工作的情况下。我想问的是如果是在一个集群里,这个线程数又该怎么计算?
    例如有三台机器构成一个集群,这三台机器的cpu分别是8核,4核,2核。就打算是cpu密集型,这时候该怎么计算线程数?

    作者回复: 每台机器算自己的,发挥出每台机器的硬件能力就可以了

    
     2
  • walkingonair
    2019-03-21
    当I/O 耗时远远大于CPU耗时时,"2 * CPU 的核数 + 1"会导致所有线程在长时间下都处于等待I/O操作的状态,而无法合理利用CPU
    
     2
我们在线,来聊聊吧