1、先講下NIO編程。NIO(Non-block I/O),亦叫作非阻塞I/O編程
與Socket類和ServerSocket類相對應,NIO也提供了SocketChannel和ServerSocketChannel兩種不一樣的套接字通道實現。api
1 緩衝區Buffer數組
這裏首先介紹緩衝區的概念,NIO和原I/O的一個重要區別就是NIO庫中,全部數據都是用緩衝區處理的。安全
緩衝區實質上是一個數組。一般它是一個字節數組(ByteBuffer),也可使用其餘種類的數組。服務器
最經常使用的緩衝區是ByteBuffer,提供了一組功能用於操做byte數組。網絡
2 通道Channel併發
通道和流的不一樣之處在於通道是雙向的,流只是一個方向上移動。能夠用於讀、寫或者二者同時進行。框架
下面看下Channel的類圖繼承關係異步
能夠看出實際上Channel能夠分爲兩大類:用於網絡讀寫的SelectableChannel和用於文件操做的FileChannel。性能
3 多路複用器Selector
簡單來說,Selector會不斷地輪詢註冊在其上的Channel,若是某個Channel上面發生讀或者寫事件,這個Channel就處於就緒狀態,會被Selector輪詢出來,而後經過SelectionKey能夠獲取就緒Channel的集合,進行後續的I/O操做。
NIO服務端序列圖
NIO客戶端序列圖
現總結NIO編程的優勢,以下:
(1)客戶端發起的鏈接操做是異步的,能夠經過在多路複用器註冊OP_CONNECT等待後續結果,不須要像以前的客戶端那樣被同步阻塞。
(2)SocketChannel的讀寫操做都是異步的,若是沒有可讀寫的數據它不會同步等待,直接返回,這樣I/O通訊線程就能夠處理其餘的鏈路,不須要同步等待這個鏈路可用。
(3)一個Selector線程能夠同時處理成千上萬個客戶端鏈接,並且性能不會隨着客戶端的增長而線性降低。很是適合作高性能、高負載的網絡服務器。
雖然,NIO有衆多優點,可是不意味着全部的Java網絡編程都必需要選擇NIO和Netty,具體選擇什麼樣的I/O模型或者NIO框架,徹底基於業務的實際應用場景和性能訴求,若是客戶端併發鏈接數很少,周邊對接的網元很少,服務器的負載也不重,那就徹底不必選擇NIO作服務端;若是是相反狀況,那就要考慮選擇合適的NIO框架進行開發。
2、選擇Netty的理由
做爲一個NIO服務端,須要可以處理網絡的閃斷、客戶端的重複接入、客戶端的安全認證、消息的編解碼、半包讀寫等狀況,若是沒有足夠的NIO編程經驗,一個NIO框架的穩定每每須要半年甚至更長的時間。
更爲糟糕的是,一旦在生產環境中發生問題,每每會致使跨節點的服務調用中斷,嚴重的可能會致使整個集羣環境都不可用,須要重啓服務器,這種很是停機會帶來巨大的損失。
從可維護性角度看,因爲NIO採用了異步非阻塞編程模型,並且是一個I/O線程處理多條鏈路,它的調試和跟蹤很是麻煩,特別是生產環境中的問題,咱們沒法進行有效的調試和跟蹤,每每只能靠一些日誌來輔助分析,定位難度很大。
使用NIO框架Netty來進行NIO編程,它既能夠做爲客戶端也能夠做爲服務端,同時支持UDP和異步文件傳輸,功能很是強大。
3、爲何選擇Netty
Netty的優勢總結以下:
1 api使用簡單,開發門檻低;
2 功能強大,預置了多種編解碼功能,支持多種主流協議;
3 定製能力強,能夠經過ChannelHandler對通訊框架進行靈活地擴展;
4 性能高,經過與其餘業界主流的NIO框架對比,Netty的綜合性能最優;
5 成熟穩定
6 社區活躍,版本迭代週期短,發現的Bug能夠及時修復