为什么Netty线程池默认大小为CPU核数的2倍

简介: 有位工作5年的小伙伴问我说,为什么Netty线程池默认大小为CPU核数的2倍,今天,我花2分钟时间给大家专门分享一下我对这个问题的理解。

有位工作5年的小伙伴问我说,为什么Netty线程池默认大小为CPU核数的2倍,今天,我花2分钟时间给大家专门分享一下我对这个问题的理解。


另外,我花了1个多星期把往期的面试题解析配套文档准备好了,想获取的小伙伴可以在我的煮叶简介中找到。

1、分析原因

我们都知道使用多线程的本质是为了提升程序的性能,总体来说有两个最核心的指标,一个延迟,一个吞吐量。延迟指的是发出请求到收到响应的时间,吞吐量指的是 。这两个指标之间有一定的关联,因为同等条件下延迟越短吞吐量越大,但由于它们是不同的维度,一个是时间,一个是空间,并不能相互转换。

因此,提升性能最主要的目的就是要降低延迟,提高吞吐量。

d09f7114d6794bd9ae4230c7c51a70d5.png

那我们如何来衡量这些性能指标呢?

2、如何衡量性能指标

具体来说,要降低延时,就是要提高CPU的处理能力。而提高吞吐量,就是要提高IO读写效率。那么具体如何衡量系统性能,我从以下两个方面来分析:

我们可以将程序分为是I/O密集型任务和CPU密集型任务。

那么第1种情况,对于CPU密集型任务而言,理论上“线程的数量 = CPU核数”就是合适的。但是,在实际应用中的线程数量一般会设置为“CPU核数 + 1”。因为线程有可能因为内存页失效或其他原因导致阻塞,多设置一个线程可以保证CPU的利用率。

ef3f71c9e7ab443fa748104368ead44b.png

第2种情况,而对于I/O密集型任务而言,我们假设CPU计算和I/O操作的耗时比是 1:1,那么2个线程是最合适的。如果CPU计算和I/O操作的耗时比是 1:2,也就是说3个线程是合适的,这样CPU和I/O设备的利用率都可以达到100%。根据这个推测,我们可以得到这样一个公式:

最佳线程数 = 1 +(IO耗时/CPU耗时)

42e1ae49bda34cc880b521bc9ae2529e.png

不过上面这个公式是针对单核CPU,如果是多核CPU只需要等比扩大就可以了,假设IO耗时和CPU耗时比为R,那么计算公式如下:

最佳线程数 = CPU核数 *(1 + R)

5637b9ec24094dcba4d03678adef047b.png

而Netty的默认线程池个数,就是假设了I/O耗时和CPU耗时的占比是1:1,实际上Netty有一个参数叫ioRatio,默认为50,它表示在一个轮事件循环中,单个I/O线程执行I/O事件和执行异步任务的耗时占比为 1:1。相当于 R = 1,代入上面的公式,就可以得出Netty默认设置的线程池大小自然就是

默认线程池大小 = CPU核数 * (1 + 1)

7fee8b3f59ed416092f172a196956e52.png

也就2倍CPU核数大小。而且Netty的应用场景主要是I/O密集型任务,所以,Netty这样设计是有科学性的。

看到了这里,你是不是豁然开朗了呢?

3、总结与使用建议

通过前面的分析,我们已经知道了Netty线程池默认大小未CPU核数2倍的原因,我们在实际开发中,如何来得到一个比较准确的线程池大小呢?

6d644e3ef7494e40929b59ac8324a116.png

我们可以提前压测,根据压测结果来进行微调。一般情况下,保证生产环境为压测环境的75%即可。如果修改Netty的线程池大小,也一定要考虑ioRatio这个参数是否需要调整,因为2倍CPU核数的大小是假设的I/O耗时和CPU耗时为1:1,调整线程大小之后,性能效果也不一定符合期望值。

a9ccb4f9b7d14b388562c802b4920fdb.png

在大部分场景下,没有必要太过于关注线程池大小怎么配置,I/O密集型任务使用Netty默认配置就可以了。因为,提高吞吐量也不能只简单的只依赖线程池,还可以通过缓存、微服务拆分,优化业务逻辑、优化算法等方式来协作解决。


我是被编程耽误的文艺Tom,如果我的分享对你有帮助。关注我,面试不再难!

相关文章
|
9月前
|
Linux
Linux 查看进程PID和线程CPU和内存占用情况
Linux 查看进程PID和线程CPU和内存占用情况
939 0
|
4月前
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
112 0
|
6月前
|
编解码 网络协议 API
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
|
6月前
|
缓存 监控 Linux
在Linux中,如何看当前系统有几颗物理CPU和每颗CPU的核数?
在Linux中,如何看当前系统有几颗物理CPU和每颗CPU的核数?
|
3月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
3月前
|
Java
.如何根据 CPU 核心数设计线程池线程数量
IO 密集型:核心数*2 计算密集型: 核心数+1 为什么加 1?即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保 CPU 的时钟周期不会被浪费。
152 4
|
6月前
|
算法 Windows
CAE如何基于CPU最佳核数和token等计算成本
【8月更文挑战第26天】在使用CAE(计算机辅助工程)进行分析计算时,需综合考虑CPU核数和token对成本的影响。CPU核数越多,虽能加速计算,但过多核数会因通信开销和内存带宽限制导致性能提升放缓。成本计算需考虑硬件租赁或购买费用及云服务收费标准。Token作为软件许可,需分摊到每次计算中。通过测试优化找到性能与成本的平衡点,实现最低成本下的高效计算。
114 1
|
7月前
|
Java
Jstack 查看线程状态及定位占用 cpu 较高的 java 线程
Jstack 查看线程状态及定位占用 cpu 较高的 java 线程
781 2
|
7月前
|
存储 缓存 NoSQL
Redis性能优化问题之优化 Redis fork 耗时严重的问题,如何解决
Redis性能优化问题之优化 Redis fork 耗时严重的问题,如何解决
|
9月前
|
存储 缓存 关系型数据库
【如何选择Mysql服务器的CPU核数及内存大小】
【如何选择Mysql服务器的CPU核数及内存大小】
607 0