大厂面试题-为什么Netty线程池默认大小为CPU核数的2倍

2023-11-03 05:52

本文主要是介绍大厂面试题-为什么Netty线程池默认大小为CPU核数的2倍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1、分析原因

2、如何衡量性能指标

3、总结与使用建议


1、分析原因

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

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

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

2、如何衡量性能指

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

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

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

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

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

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

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

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

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

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

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

3、总结与使用建

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

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

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

这篇关于大厂面试题-为什么Netty线程池默认大小为CPU核数的2倍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/336041

相关文章

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

MySQL9.0默认路径安装下重置root密码

《MySQL9.0默认路径安装下重置root密码》本文主要介绍了MySQL9.0默认路径安装下重置root密码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录问题描述环境描述解决方法正常模式下修改密码报错原因问题描述mysqlChina编程采用默认安装路径,

MySQL8.0设置redo缓存大小的实现

《MySQL8.0设置redo缓存大小的实现》本文主要在MySQL8.0.30及之后版本中使用innodb_redo_log_capacity参数在线更改redo缓存文件大小,下面就来介绍一下,具有一... mysql 8.0.30及之后版本可以使用innodb_redo_log_capacity参数来更改

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH

java父子线程之间实现共享传递数据

《java父子线程之间实现共享传递数据》本文介绍了Java中父子线程间共享传递数据的几种方法,包括ThreadLocal变量、并发集合和内存队列或消息队列,并提醒注意并发安全问题... 目录通过 ThreadLocal 变量共享数据通过并发集合共享数据通过内存队列或消息队列共享数据注意并发安全问题总结在 J

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片