淺談使用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上不存在性能問題。html

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

在最近三四天,我又重寫了代碼,此次用AIO重寫以前完成的NIO代碼花費的時間明顯比NIO重寫BIO花費的時間短不少,主要緣由是AIO和NIO在處理業務方面的代碼有不少類似的地方。windows

 

使用AIO重寫代碼後,用ab進行大量的併發測試,測試的結果以下:服務器

• 在沒有開啓HTTP的持久鏈接(Connection: close)狀況下:網絡

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

 

• 在開啓HTTP的持久鏈接(Connection: keep-alive)狀況下:異步

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

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。

 

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

相關文章
相關標籤/搜索