淺談使用NIO,AIO的感受


花了十多天的時間把原來的WEB服務由BIO(阻塞IO)模式改寫成NIO(非阻塞IO)模式,然后在xp機子上用ab測試並發性能,確實提升了30%左右的並發性能,測試完成后,當時感覺還是挺滿意的。幾天前在網上看到有文章中談到關於NIO中的select()在windows機子上的實現有性能問題,原因是NIO在windows上使用的是select/poll技術(網上有文章指出:select ()最不能忍受的是一個進程所打開的FD是有一定限制的,由FD_SETSIZE設置,默認值是2048。對於那些需要支持幾千上萬連接服務器來說顯然太少了。傳統的select/poll另一個致命弱點就是當你擁有一個很大的socket集合,不過由於網絡延時,任一時間只有部分的socket是"活躍"的,但是select/poll每次調用都會線性掃描全部的集合,導致效率呈現線性下降。但是epoll不存在這個問題。),但在linux2.6+上,Java的NIO實現為epoll,所以在linux上不存在性能問題。

然后看到一些資料中提到,jdk7新增的異步IO(AIO)在windows上實現為IOCP,解決了NIO在windows上高並發時遇到的性能問題。

在最近三四天,我又重寫了代碼,這次用AIO重寫之前完成的NIO代碼花費的時間明顯比NIO重寫BIO花費的時間短很多,主要原因是AIO和NIO在處理業務方面的代碼有很多相似的地方。

 

使用AIO重寫代碼后,用ab進行大量的並發測試,測試的結果如下:

• 在沒有開啟HTTP的持久連接(Connection: close)情況下:

用ab進行壓力測試,在100-1000並發的情況下,AIO比NIO的並發性能提升了10%左右。

 

• 在開啟HTTP的持久連接(Connection: keep-alive)情況下:

1. 在50 - 200並發的情況下,AIO比NIO的並發性能慢了20%左右。

2. 在200 - 500並發的情況下,AIO比NIO的並發性能慢了10% - 5%左右。

3. 在500 - 1000並發的情況下,AIO與NIO並發性能基本持平,有的時候還表現更快一些。

我的xp機子上,ab最大只能開到1000,1000+的情況,我沒測試。

 

原以為使用AIO重寫的代碼在各個方面都會強於NIO,曾經因為這個測試結果困擾了我一二天時間。

 

今天上午在CSDN上看到一篇性能調優攻略:http://sd.csdn.net/a/20120621/2806814_2.html,其中有一段內容提到異步IO:

異步操作。我們知道Unix下的文件操作是有block和non-block的方式的,像有些系統調用也是block式的,如:Socket下的select,Windows下的WaitforObject之類的,如果我們的程序是同步操作,那么會非常影響性能,我們可以改成異步的,但是改成異步的方式會讓你的程序變復雜。異步方式一般要通過隊列,要注間隊列的性能問題,另外,異步下的狀態通知通常是個問題,比如消息事件通知方式,有callback方式,等,這些方式同樣可能會影響你的性能。但是通常來說,異步操作會讓性能的吞吐率有很大提升(Throughput),但是會犧牲系統的響應時間(latency)。這需要業務上支持。

 

通過AIO重寫的代碼可以看出,AIO的每一次callback(回調)是通過線程池中的一個線程執行的,而我之前寫的NIO代碼僅在一個線程中執行(僅使用一個selector),可能因此在開啟持久連接時,低並發的情況下會出現AIO的並發性能還不如NIO,當並發數越來越高的時候,測試結果也表明,AIO的並發性能開始慢慢接近甚至超越NIO。

 

此時,之前的困擾已漸漸的散去。 

 

2012-06-25


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM