Java 最佳线程数怎么得来?

2021-01-05 19:17:24 +08:00
 shangzhanyu
根据公式:服务器端最佳线程数量=((线程等待时间+线程 cpu 时间)/线程 cpu 时间) * cpu 数量,算出来的数量不过百,但是实际情况 service 的线程数又设置的 500 甚至更多,又看了 HotSpot 用的 1:1 内核线程,搞懵逼了。。。
6358 次点击
所在节点    Java
50 条回复
xbh1794970183564
2021-01-05 19:18:57 +08:00
这里的线程主要是一直在运行的线程数吧,hotspot 后台一直进行垃圾收集,线程数太多肯定影响使用,service 里面 500 多应该大部分都是 WAITING 状态,真正在运行的没多少
xbh1794970183564
2021-01-05 19:20:38 +08:00
@xbh1794970183564 mark,蹲个大佬回答
shangzhanyu
2021-01-05 19:20:55 +08:00
@xbh1794970183564 是的,运行中的不多,所以没搞懂有些服务设置 500 有啥用。。。
shaoyijiong
2021-01-05 19:23:39 +08:00
其实那些写 service 的人根本就没考虑过你说的最佳线程数 😂
xbh1794970183564
2021-01-05 19:23:50 +08:00
@shangzhanyu 我们服务启动有 200 线程左右,很多都是框架相关的,自己的线程池一般是 IO 任务 CPU*2 线程,计算密集就是 CPU 核心数
php8
2021-01-05 19:56:02 +08:00
使用 eventloop 的 nonblocking 应用,eventloop 线程数设置为 CPU 核心数的 2 倍,这是个推荐值,超过这个值不能提高吞吐量,小于这个值降低吞吐上限,性能够用设置为 1 或 2 也行。

blocking IO 密集型应用,比如 springmvc 那套 web,线程是用来等 IO 的,假设每个请求 IO 等待 1 秒,线程数≈qps,500 线程就是 500 qps,某些场景等待时间 5 秒,500 线程就是 100qps 。

现代 linux 和 jvm,维持几千个等待 IO 的线程开销很小,所以很多地方推荐 200 或者 500 。

计算公式是对的,但也要看具体情况,还有其他因素要考虑。
liuch
2021-01-05 20:22:37 +08:00
书上、网上这些所谓的公式,都偏理想化,实际指导意义不大。生产环境,最好是根据 ThreadPoolExecutor 的统计数据,分析做调整,最好支持动态。特别是微服务里面各种复杂的调用相关的
YouLMAO
2021-01-05 20:26:43 +08:00
我们一天处理大概 2 万亿 request,c++, 单容器 16c 开 16 工作线程池,开这么多想干嘛,都是 epoll 了,io 不阻塞工作线程的
pkwenda
2021-01-05 20:58:40 +08:00
主要还是看 io 密集性,如果不密集 & 内存允许的情况,个人项目我开的比较随意 ( jvm 单个线程默认 1M+ 的内存)
neoblackcap
2021-01-05 21:05:26 +08:00
我就提一个吧,你们都是跑在物理机上面吗?要不然还是按 @liuch 的说,根据统计模型来调吧。
书本上的东西很理想化的。虚拟机的 CPU 调度就能将所谓的最优碾烂。
Rorysky
2021-01-05 23:47:18 +08:00
@YouLMAO 啥业务这么巨量
90d0n
2021-01-06 09:15:41 +08:00
How to Find the Optimal Database Connection Pool Size
A formula which has held up pretty well across a lot of benchmarks for years is that for optimal throughput the number of active connections should be somewhere near ((core_count * 2) + effective_spindle_count). Core count should not include HT threads, even if hyperthreading is enabled. Effective spindle count is zero if the active data set is fully cached, and approaches the actual number of spindles as the cache hit rate falls. Benchmarks of WIP for version 9.2 suggest that this formula will need adjustment on that release. There hasn't been any analysis so far regarding how well the formula works with SSDs.

However you choose a starting point for a connection pool size, you should probably try incremental adjustments with your production system to find the actual "sweet spot" for your hardware and workload.

Remember that this "sweet spot" is for the number of connections that are actively doing work. Ignore mostly-idle connections used for system monitoring and control when working out an appropriate pool size. You should always make max_connections a bit bigger than the number of connections you enable in your connection pool. That way there are always a few slots available for direct connections for system maintenance and monitoring.

https://wiki.postgresql.org/wiki/Number_Of_Database_Connections
90d0n
2021-01-06 09:17:03 +08:00
postgre 数据库推荐的设置方式, 一直在生产上这么设置没出啥问题
shangzhanyu
2021-01-06 09:27:06 +08:00
@YouLMAO 同感,设置那么多不知道干啥,大部分都在等待状态
shangzhanyu
2021-01-06 09:32:31 +08:00
@neoblackcap 对哦,跑在虚拟机上确实和物理机不一样。。。
shangzhanyu
2021-01-06 09:38:26 +08:00
@liuch 就是想搞懂为什么设置这么大的线程数还没问题,按理说这么多线程上下文切换行得通么,机器配置 8c 8g
BBCCBB
2021-01-06 09:51:41 +08:00
根据压测得到.
wysnylc
2021-01-06 10:07:53 +08:00
尽信书,不如无书
hangszhang
2021-01-06 10:18:17 +08:00
美团有一篇文章说这个的, 大意是公式与生产有偏差, 需要做压测然后支持动态调整参数
php8
2021-01-06 10:18:46 +08:00
@shangzhanyu IO 密集型应用,开那么多线程的作用就是等待,一个请求阻塞一个线程,如果阻塞 1 秒钟,开 10 个线程每秒只能处理 10 个请求,开 100 个性能就提高到 100qps 了。就算开几万个这类线程,切换开销都能小到忽略不计。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/741974

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX