2014-09-30 18 views
-2

我知道有很多利用java.nio的非阻塞I/O的開源服務器程序,比如Mina。許多實現使用多個選擇器和多線程來處理選定的事件。這似乎是一個完美的設計。java.nio非阻塞I/O的瓶頸是什麼?

是嗎?基於NIO的服務器的瓶頸是什麼?好像不會有什麼?

是否有任何需要控制連接的數量?一個人會怎麼做?

+1

定義'performance'這意味着大約相當於斷章取義爲'faster'或'better' ... – 2014-09-30 03:33:42

回答

1

基於NIO的服務器的瓶頸是什麼?

網絡,內存,CPU,所有常見的東西。

這似乎不會有什麼?

爲什麼?

是否有任何需要控制連接數量?

不是。

這樣做會怎樣?

計數他們進出,並取消登記OP_ACCEPT,而你是最大的。

+0

謝謝您的回答,更重要的是,我沒有發現任何的做法來控制連接數量。那麼是否需要這樣做?如果不控制它,CPU /內存可能失控? – jiafu 2014-09-30 03:19:39

+0

以米娜爲例。如何控制連接數量? – jiafu 2014-09-30 03:20:52

+0

我已經回答了這兩個問題。事實上,我已經回答了*所有*你的問題。我的答案的哪一部分你不瞭解? – EJP 2014-09-30 03:23:59

3

對於傳統的阻塞I/O,每個連接必須由一個或多個專用線程處理。隨着連接數量的增加,所需線程的數量也在增加。這種模式的工作原理合理,連接數量達到數百或數千,但不能很好地擴展。

複用和非阻塞I/O反轉模型,允許一個線程爲許多不同的連接提供服務。它通過選擇活動連接,並且只有在確保套接字準備就緒後才執行I/O。

這是一個更具可擴展性的解決方案,因爲現在你沒有大部分非活動線程圍繞在他們的拇指周圍。相反,您可以在所有套接字之間穿梭一個或幾個非常活躍的線程。那麼這裏的瓶頸是什麼?

  • 一個基於NIO的服務器仍受其CPU限制。隨着插槽的數量和I/O數量的增加,CPU將越來越繁忙。

  • 多路複用線程需要儘快服務套接字。他們只能一次一個地工作。如果服務器不小心,這些線程可能會有太多工作要做。當發生這種情況時,可能需要一些小心謹慎的編程來將工作移出脫機線程。

  • 如果傳入的數據無法立即處理,可能會謹慎地將其複製到單獨的內存緩衝區,因此它不在操作系統的隊列中。該複製需要時間和額外的內存。

  • 程序不能有文件描述符無限數量/內核處理開放。每個套接字在操作系統中都有相關的讀寫緩衝區,所以您最終會遇到操作系統的限制。

  • 很顯然,你還是你的硬件和網絡基礎設施的限制。服務器受其NIC,受其他網絡中繼帶的帶寬和延遲等限制。

這是一個非常通用的答案。要真正回答這個問題,你需要檢查有問題的特定服務器程序。每個節目都是不同的。可以說,任何特定的程序都可能存在瓶頸,而這些瓶頸並不是Java NIO的「故障」。

+0

非常感謝你,是否需要控制連接的數量?如果沒有控制,最終可能會發生oom或其他問題。如何控制它? – jiafu 2014-09-30 03:52:58

+0

如果傳入的數據不能立即處理,將更有意義,只是停止OP_READ該連接上,在操作系統的緩衝區保持數據,不要在這上面花更多的內存,讓發送方失速。 – EJP 2014-09-30 04:43:44

+0

@EJP對於部分消息,您可能不知道您是否可以在不先讀取數據的情況下處理數據。本週我一直在處理這個問題,將我的SSL代碼重寫爲非阻塞。如果有數據可用,我不知道在讀取緩衝數據並將其提供給SSL引擎之前是否有完整的SSL數據包。它可能會消耗數據,也可能會拒絕。 – 2014-09-30 05:16:32