请教下关于 Tomcat 线程池和 Java 中 ExecutorService 线程池的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
VB1
V2EX    Java

请教下关于 Tomcat 线程池和 Java 中 ExecutorService 线程池的问题

  •  1
     
  •   VB1 2023 年 12 月 8 日 3312 次点击
    这是一个创建于 868 天前的主题,其中的信息可能已经有所发展或是发生改变。

    咨询下各位大佬,为什么 tomcat 的默认的最大的线程数是 200 ,但是在项目里面( IO 密集型)设置的最大线程数是 2 * CPU 核心数?

    10 条回复    2023-12-08 16:57:02 +08:00
    themostlazyman
        1
    themostlazyman  
       2023 年 12 月 8 日
    Tomcat 多个线程为了提高并发(IO 密集); 2 * CPU 核心数一般是处理器支持一个核虚拟两个核的 CPU 的设置(计算密集或者多进程应用)。
    huang119412
        2
    huang119412  
       2023 年 12 月 8 日
    IO 密集型线程数设为 2 * CPU ,此时的 IO 是 NIO , 如果是 OIO 则线程数是 2 * CPU 不合理,Tomcat 一般需要配合关系型数据库使用,Web 项目的瓶颈都是在数据库,而 JDBC (关系型数据库)并不支持异步,异步也没什么意义,所以 Tomcat 的线程数设置的看起来非常多。但是线程的切换时间和 IO 的阻塞时间比基本上可以忽略不记。
    VB1
        3
    VB1  
    OP
       2023 年 12 月 8 日
    @themostlazyman
    @huang119412
    感谢二位的回答,但是一个 springboot 里面,内置 tomcat ,在一台机器上(假设 CPU8 核)启动 springboot 项目后,所有的线程共享这台机器的 CPU ,但是为啥 tomcat 的线程数(最大 200)和项目中线程池的线程数(最大 16)相差如此之大。也就是说为什么 tomcat 可以不受这个 2 * CPU 核心数这个限制?
    Sezxy
        4
    Sezxy  
       2023 年 12 月 8 日
    每个请求到在线程池的一个线程处理,大部分请求都由于外部 IO 请求而阻塞,导致该请求所在的线程阻塞
    如果同一秒内所有请求都阻塞在 IO 上(如查询 Mysql ),那么此时 CPU 就变得空闲了
    加大线程池最大线程数量,可以在同 1 秒内处理更多请求,更好利用 CPU
    但线程数量也不能无限大,频繁的上下文切换也是很消耗 CPU 的
    升级 JDK21 后可以尝试虚拟线程,这种场景能更好的提高 CPU 利用率
    yty2012g
        5
    yty2012g  
       2023 年 12 月 8 日
    后面的设置不太合理,如果是 IO 密集型,很容易出现线程池内线程不够用的情况
    anonydmer
        6
    anonydmer  
       2023 年 12 月 8 日   1
    楼主混淆了两个概念,servlet 容器的线程池和应用业务的线程池。tomcat 配置的 200 个线程是用来处理 servlet 请求的,就是说,有请求到来时候,tomcat 总共用多少个线程来处理请求的业务逻辑操作(不是请求本身的 io ),这个逻辑操作对应的就是你 spring mvc 中某个 controller 的一个 action 方法。 在这些业务逻辑操作中,如果你还需要做多线程操作,就需要你自己管理一个线程池,就是你说的后面这个线程池,因为在业务中一般都是做 io 操作,io 操作不需要很多的线程数量就够了。
    anonydmer
        7
    anonydmer  
       2023 年 12 月 8 日
    在这种模式下,tomcat 的并发性能其实是受到最大线程数量限制的。太多的线程会对 CPU 造成频繁的上下文切换。 如果系统是 IO 密集型的,针对这个问题先前一种可行的方式是用事件驱动的框架,例如 Spring WebFlux; 但是现在 Java 21 已经支持了虚拟线程,我们可以在不改变编程模型的基础上达到和 SpringWebFlux 类型的性能,目前 SpringBoot 已经支持虚拟现场了,楼主可以测试一下让 tomcat 用虚拟线程,在 IO 场景下,性能会好很多。
    wysnxzm
        8
    wysnxzm  
       2023 年 12 月 8 日
    virtual thread 对这类问题是降维打击
    JYii
        9
    JYii  
       2023 年 12 月 8 日
    @wysnxzm #8 是的,springboot3.2.0 支持配置 spring.threads.virtual.enabled=true ,以后再也不用配置什么线程池了
    VB1
        10
    VB1  
    OP
       2023 年 12 月 8 日
    @anonydmer 明白了,感谢解惑。业务逻辑操作中确实很少有需要另外再做多线程操作的,再加上 io 密集型的原因,也就不需要很多的线程数量。2 * CPU 的核心数能涵盖很多场景。


    @wysnxzm
    @JYii
    这就去学习虚拟线程,感谢回复。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3057 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 164ms UTC 02:38 PVG 10:38 LAX 19:38 JFK 22:38
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86