摘自:http://blog.csdn.net/u010154380/article/details/64443762java
《Netty 權威指南》—— 選擇Netty的理由編程
聲明:本文是《Netty 權威指南》的樣章,感謝博文視點受權併發編程網站發佈樣章,禁止以任何形式轉載此文。緩存
在開始本節以前,我先講一個親身經歷的故事:曾經有兩個項目組同時用到了NIO編程技術,一個項目組選擇本身開發NIO服務端,直接使用JDK原生的API,結果2個多月過去了,他們的NIO服務端始終沒法穩定,問題頻出。因爲NIO通訊是它們的核心組件之一,所以,項目的進度受到了嚴重的影響,領導對此很是惱火。另外一個項目組直接使用Netty做爲NIO服務端,業務的定製開發工做量很是小,測試代表,功能和性能都徹底達標,項目組幾乎沒有在NIO服務端上花費額外的時間和精力,項目進展也很是順利。安全
這兩個項目組的不一樣遭遇提醒咱們:開發出高質量的NIO程序並非一件簡單的事情,除去NIO固有的複雜性和BUG不談,做爲一個NIO服務端須要可以處理網絡的閃斷、客戶端的重複接入、客戶端的安全認證、消息的編解碼、半包讀寫等等,若是你沒有足夠的NIO編程經驗積累,一個NIO框架的穩定每每須要半年甚至更長的時間。更爲糟糕的是一旦在生產環境中發生問題,每每會致使跨節點的服務調用中斷,嚴重的可能會致使整個集羣環境都不可用,須要重啓服務器,這種非正常停機會帶來巨大的損失。服務器
從可維護性角度看,因爲NIO採用了異步非阻塞編程模型,並且是一個IO線程處理多條鏈路,它的調試和跟蹤很是麻煩,特別是生產環境中的問題,咱們沒法有效調試和跟蹤,每每只能靠一些日誌來輔助分析,定位難度很大。網絡
2.6.1.不選擇JAVA原生NIO編程的緣由多線程
在本小節,咱們總結下爲何不建議開發者直接使用JDK的NIO類庫進行開發的緣由:併發
1) NIO的類庫和API繁雜,使用麻煩,你須要熟練掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等;app
2) 須要具有其它的額外技能作鋪墊,例如熟悉Java多線程編程,由於NIO編程涉及到Reactor模式,你必須對多線程和網路編程很是熟悉,才能編寫出高質量的NIO程序;框架
3) 可靠性能力補齊,工做量和難度都很是大。例如客戶端面臨斷連重連、網絡閃斷、半包讀寫、失敗緩存、網絡擁塞和異常碼流的處理等等,NIO編程的特色是功能開發相對容易,可是可靠性能力補齊工做量和難度都很是大;
4) JDK NIO的BUG,例如臭名昭著的epoll bug,它會致使Selector空輪詢,最終致使CPU 100%。官方聲稱在JDK1.6版本的update18修復了該問題,可是直到JDK1.7版本該問題仍舊存在,只不過該bug發生機率下降了一些而已,它並無被根本解決。該BUG以及與該BUG相關的問題單以下:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6403933
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719
異常堆棧以下:
01
java.lang.Thread.State: RUNNABLE
02
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
03
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
04
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
05
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
06
- locked <0x0000000750928190> (a sun.nio.ch.Util2)
07
- locked <0x00000007509281a8> (a java.util.Collections2) 07 - locked <0x00000007509281a8> (a java.util.CollectionsUnmodifiableSet)
08
- locked <0x0000000750946098> (a sun.nio.ch.EPollSelectorImpl)
09
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
10
at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:217)
11
at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:836)
因爲上述緣由,在大多數場景下,我不建議你們直接使用JDK的NIO類庫,除非你精通NIO編程或者有特殊的需求,在絕大多數的業務場景中,咱們可使用NIO框架Netty來進行NIO編程,它既能夠做爲客戶端也能夠做爲服務端,同時支持UDP和異步文件傳輸,功能很是強大。
下個小節咱們就看看爲何選擇Netty做爲基礎通訊框架。
2.6.2.爲何選擇Netty
Netty是業界最流行的NIO框架之一,它的健壯性、功能、性能、可定製性和可擴展性在同類框架中都是數一數二的,它已經獲得成百上千的商用項目驗證,例如Hadoop的RPC框架avro使用Netty做爲底層通訊框架。不少其它業界主流的RPC框架,也使用Netty來構建高性能的異步通訊能力。
經過對Netty的分析,咱們將它的優勢總結以下:
1) API使用簡單,開發門檻低;
2) 功能強大,預置了多種編解碼功能,支持多種主流協議;
3) 定製能力強,能夠經過ChannelHandler對通訊框架進行靈活的擴展;
4) 性能高,經過與其它業界主流的NIO框架對比,Netty的綜合性能最優;
5) 成熟、穩定,Netty修復了已經發現的全部JDK NIO BUG,業務開發人員不須要再爲NIO的BUG而煩惱;
6) 社區活躍,版本迭代週期短,發現的BUG能夠被及時修復,同時,更多的新功能會被加入;
7) 經歷了大規模的商業應用考驗,質量已經獲得驗證。在互聯網、大數據、網絡遊戲、企業應用、電信軟件等衆多行業獲得成功商用,證實了它能夠徹底知足不一樣行業的商業應用。
正是由於這些優勢,Netty逐漸成爲Java NIO編程的首選框架。
2.7 .總結
本章經過一個簡單的demo開發-時間服務器程序,讓你們熟悉傳統的同步阻塞IO、僞異步IO、非阻塞IO(NIO)和異步IO(AIO)的編程和使用差別。而後對比了各自的優缺點,給出了使用建議。
最後,咱們詳細介紹了爲何不建議讀者朋友們直接使用JDK的NIO原生類庫進行異步IO的開發,同時對Netty的優勢進行分析和總結,給出使用Netty進行NIO開發的理由。
相信學完本章以後,你們對Java的網絡編程已經有了初步的認識,從下一個章節開始,咱們正式進入Netty的世界,學習和掌握基於Netty的網絡開發。