新聞中心
I/O密集型業(yè)務(wù),線程數(shù)量要設(shè)置成 CPU 的 2 倍!

也不知道這是哪本書的坑爹理論,現(xiàn)在總有一些小青年老拿著這樣的定理來說教。說的信誓旦旦,毋庸置疑,仿佛是權(quán)威的化身。討論時把這樣的理論當作前提,真的是受害不淺。
但可惜的是,這樣的理論站不住腳。我只需要一個簡單的反問,它就不攻自破:
Tomcat的默認線程數(shù)是多少呢?
它既不是 CPU 的 2 倍,也不是什么其他數(shù)值。在某些高并發(fā)的服務(wù)中,它的核心線程數(shù),可能達到數(shù)千甚至上萬。對于一個Tomcat來說,它處理的大多數(shù)都是I/O密集型的業(yè)務(wù),可以說是最好的實踐場景。
要明白這個線程數(shù)設(shè)置的玄機,就必須了解I/O請求的特點。I/O請求不僅僅指的是磁盤讀寫,在互聯(lián)網(wǎng)服務(wù)中更多指的是網(wǎng)絡(luò)I/O請求。
I/O請求的速度,要遠低于CPU運行的速度。大部分I/O請求,在發(fā)起之后,就進入等待狀態(tài),這個等待狀態(tài)不會浪費CPU,所以一臺機器在同一時刻支持的I/O請求,可以很多。
如果I/O請求的速度比較快,和CPU的耗時對等的時候,我們把處理I/O的線程數(shù),設(shè)置成 CPU 的 2倍,是合理的。但現(xiàn)實中并沒有這么多如果,我們要處理秒成千上萬的I/O請求,注定了它的耗時要比CPU多的多。
像RPC組件,比如Dubbo服務(wù)端,也會設(shè)置一個比較大的線程數(shù)(比如600);Feign這種就更不用多說了,短連接意味著更多線程數(shù)的支持。這都是些最佳實踐。
雖然I/O線程數(shù)量增多,會造成非常頻繁的上下文切換,進而影響效率。但在互聯(lián)網(wǎng)應(yīng)用中,它卻是一個優(yōu)秀的解決方案。
更優(yōu)秀的解決方式也有,那就是使用協(xié)程。協(xié)程是用戶態(tài)的線程,是對普通線程更細粒度的劃分。它是在用戶態(tài)運行的,由用戶自行調(diào)度,所以也就避免了頻繁的上下文切換問題。
但協(xié)程在Java中還不成熟,它依然是Golang語言的誘人特性。使用Golang開發(fā)的Web服務(wù),可以采用更少的線程來支持大量I/O密集型的請求。
綜上所述,標題的表述并不正確,而且錯的離譜。
作者簡介:小姐姐味道 (xjjdog),一個不允許程序員走彎路的公眾號。聚焦基礎(chǔ)架構(gòu)和Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。
分享標題:為什么說IO密集型業(yè)務(wù),線程數(shù)是CPU數(shù)的2倍?
URL鏈接:http://www.dlmjj.cn/article/codioeh.html


咨詢
建站咨詢
