我想在一小羣機器上支持大約10,000個同時HTTP客戶機(儘可能小)。我想在用戶使用應用程序時保持與每個客戶端的連接,以允許服務器推送更新。線程閒置=壞?
我相信異步IO通常被推薦用於這種長期連接,以避免大量線程閒置。但是讓線程閒置的問題是什麼?我發現線程模型在心理上更容易處理,但我不想做一些會讓我頭痛的事情。我想我必須進行實驗,但是我想知道是否有人知道沿着這些線的任何以前的實驗?
我想在一小羣機器上支持大約10,000個同時HTTP客戶機(儘可能小)。我想在用戶使用應用程序時保持與每個客戶端的連接,以允許服務器推送更新。線程閒置=壞?
我相信異步IO通常被推薦用於這種長期連接,以避免大量線程閒置。但是讓線程閒置的問題是什麼?我發現線程模型在心理上更容易處理,但我不想做一些會讓我頭痛的事情。我想我必須進行實驗,但是我想知道是否有人知道沿着這些線的任何以前的實驗?
異步I/O基本上意味着您的應用程序執行大部分線程調度。而不是讓操作系統隨機掛起你的線程並安排另一個線程,而只有線程達到一個I/O操作時,你的線程只有CPU核心的線程數量,並且在最合適的點—上屈服於其他任務。時間。
上面似乎是從性能的角度來看一個明確的勝利,但異步編程模型是在幾個方面要複雜得多:
在另一方面,許多有利於改進和優化都發生在現代操作系統的其中大多是消除同步我的表現缺點/ O編程:
一個經典論文通過多以上和其他一些點會是一個很好的補充,我所說的是什麼:
https://www.usenix.org/legacy/events/hotos03/tech/full_papers/vonbehren/vonbehren_html/index.html
在你的問題的評論中已經有一些好的指針。
不使用10K線程的原因是這種成本內存資源和內存成本的能源。編程模型沒有參數,因爲坐在客戶端連接上的線程不能與要發佈事件的線程相同。
請看看Servlet 3.0標準中的websockets標準和異步請求處理模型。所有最近的Java Web應用程序服務器現在都實現它(例如Glassfish和Tomcat),它是解決您的問題的方案。
由於您使用的操作系統,JVM和應用程序服務器缺失,此問題本身無法應答。但是,您可以自己快速測試它,只需創建一個帶有Thread.sleep(9999999)
的servlet或JSP並對其執行siege -c 10000 ...
即可。
10,000個同時HTTP客戶端...線程坐着閒置有什麼問題?
空閒線程的代價似乎只是爲內核結構(幾kb)和線程堆棧(512kb-mb)分配的內存。但...
顯然,你會不時喚醒你的每一個n百線程,對不對?那是你付出上下文切換的代價的時候,這個時間可能不是很短(調用系統調度器的時間,更多的緩存未命中等)。例如,請參閱: http://www.cs.rochester.edu/u/cli/research/switch.pdf
而且您必須非常仔細地固定您的線程,以免影響系統。因此,每個連接的線程數量(阻塞IO)架構可以增加系統與異步IO的延遲。但是如果幾乎所有的線程都停在大部分時間內,它仍然適用於你的情況。
最後的話。我們不知道您的線程將在read()中被阻塞多少次,以及他們需要做多少工作來處理接收到的數據。將使用什麼硬件,操作系統和網絡接口......因此,測試一下你係統的原型。
真正的問題是在10K線程本身的分岔。這將使用大量的堆棧空間來完成。如果你有內存,那麼它可能適用於你,但除此之外,NIO解決方案雖然更復雜,但更好。 – Gray
http://stackoverflow.com/a/17771219/1305501 – nosid
那是10k個不同的HTTP服務器嗎?如果沒有,你可能要考慮使用HTTP Keepalive並重用現有連接 – fge