1.netty 是什麼?
netty 是一個基于 java nio 類庫的異步通信架構,它的架構特點是:異步非阻塞、基于事件驅動、高性能、高可靠性和高可定制性。
2.使用 netty 能夠做什麼?
開發異步、非阻塞的 tcp 網絡應用程式;
開發異步、非阻塞的 udp 網絡應用程式;
開發異步檔案傳輸應用程式;
開發異步 http 服務端和用戶端應用程式;
提供對多種編解碼架構的內建,包括谷歌的 protobuf、jbossmarshalling、java 序列化、壓縮編解碼、xml 解碼、字元串編解碼等,這些編解碼架構可以被使用者直接使用;
提供形式多樣的編解碼基礎類庫,可以非常友善的實作私有協定棧編解碼架構的二次定制和開發;
基于職責鍊模式的 pipeline-handler 機制,使用者可以非常友善的對網絡事件進行攔截和定制;
所有的 io 操作都是異步的,使用者可以通過 future-listener 機制主動 get 結果或者由 io 線程操作完成之後主動 notify 結果,使用者的業務線程不需要同步等待;
ip 黑白名單控制;
列印消息碼流;
流量控制和整形;
性能統計;
基于鍊路空閑事件檢測的心跳檢測
……
3.netty 在哪些行業得到了應用?
網際網路行業:随着網站規模的不斷擴大,系統并發通路量也越來越高,傳統基于 tomcat 等 web 容器的垂直架構已經無法滿足需求,需要拆分應用進行服務化,以提高開發和維護效率。從組網情況看,垂直的架構拆分之後,系統采用分布式部署,各個節點之間需要遠端服務調用,高性能的 rpc 架構必不可少,netty 作為異步高性能的通信架構,往往作為基礎通信元件被這些 rpc 架構使用。
典型的應用有:阿裡分布式服務架構 dubbo 的 rpc 架構使用 dubbo 協定進行節點間通信,dubbo 協定預設使用 netty 作為基礎通信元件,用于實作各程序節點之間的内部通信。它的架構圖如下:

圖1-1 dubbo 節點間調用關系圖
其中,服務提供者和服務消費者之間,服務提供者、服務消費者和性能統計節點之間使用 netty 進行異步/同步通信。
除了 dubbo 之外,淘寶的消息中間件 rocketmq 的消息生産者和消息消費者之間,也采用 netty 進行高性能、異步通信。
除了阿裡系和淘寶系之外,很多其它的大型網際網路公司或者電商内部也已經大量使用 netty 建構高性能、分布式的網絡伺服器。
遊戲行業:無論是手遊服務端、還是大型的網絡遊戲,java 語言得到了越來越廣泛的應用。netty 作為高性能的基礎通信元件,它本身提供了 tcp/udp 和 http 協定棧,非常友善定制和開發私有協定棧。賬号登陸伺服器、地圖伺服器之間可以友善的通過 netty 進行高性能的通信,架構示意圖如下:
圖1-2 netty 在遊戲伺服器架構中的應用
大資料領域:經典的 hadoop 的高性能通信和序列化元件 avro 的 rpc 架構,預設采用 netty 進行跨節點通信,它的 netty service 基于 netty 架構二次封裝實作。
大資料計算往往采用多個計算節點和一個/n個彙總節點進行分布式部署,各節點之間存在海量的資料交換。由于 netty 的綜合性能是目前各個成熟 nio 架構中最高的,是以,往往會被選中用作大資料各節點間的通信。
企業軟體:企業和 it 內建需要 esb,netty 對多協定支援、私有協定定制的簡潔性和高性能是 esb rpc 架構的首選通信元件。事實上,很多企業總線廠商會選擇 netty 作為基礎通信元件,用于企業的 it 內建。
通信行業:netty 的異步高性能、高可靠性和高成熟度的優點,使它在通信行業得到了大量的應用。
4.使用傳統的 socket 開發挺簡單的,我為什麼要切換到 nio 進行程式設計呢?
首先我們看下傳統基于同步阻塞 io(bio)的線程模型圖:
圖1-3 同步阻塞 io(bio)線程模型圖
由上圖我們可以看出,傳統的同步阻塞 io 通信存在如下幾個問題:
線程模型存在緻命缺陷:一連接配接一線程的模型導緻服務端無法承受大量用戶端的并發連接配接;
性能差:頻繁的線程上下文切換導緻 cpu 利用效率不高;
可靠性差:由于所有的 io 操作都是同步的,是以業務線程隻要進行 io 操作,也會存在被同步阻塞的風險,這會導緻系統的可靠性差,依賴外部元件的處理能力和網絡的情況。
采用非阻塞 io(nio)之後,同步阻塞 io 的三個缺陷都将迎刃而解:
nio 采用 reactor 模式,一個 reactor 線程聚合一個多路複用器 selector,它可以同時注冊、監聽和輪詢成百上千個 channel,一個 io 線程可以同時并發處理n個用戶端連接配接,線程模型優化為1:n(n < 程序可用的最大句柄數)或者 m : n (m通常為 cpu 核數 + 1, n < 程序可用的最大句柄數);
由于 io 線程總數有限,不會存在頻繁的 io 線程之間上下文切換和競争,cpu 使用率高;
所有的 io 操作都是異步的,即使業務線程直接進行 io 操作,也不會被同步阻塞,系統不再依賴外部的網絡環境和外部應用程式的處理性能。
由于切換到 nio 程式設計之後可以為系統帶來巨大的可靠性、性能提升,是以,目前采用 nio 進行通信已經逐漸成為主流。
5.為什麼不直接基于 jdk 的 nio 類庫程式設計呢?
我們通過 jdk nio 服務端和用戶端的工作時序圖來回答下這個問題:
圖1-4 jdk nio 服務端建立和通信序列圖
即便抛開代碼和 nio 類庫複雜性不談,一個高性能、高可靠性的 nio 服務端開發和維護成本都是非常高的,開發者需要具有豐富的 nio 程式設計經驗和網絡維護經驗,很多時候甚至需要通過抓包來定位問題。也許開發出一套 nio 程式需要 1 個月,但是它的穩定很可能需要 1 年甚至更長的時間,這也就是為什麼我不建議直接使用 jdk nio 類庫進行通信開發的一個重要原因。
下面再一起看下 jdk nio 用戶端的通信時序圖:它同樣非常複雜。
圖1-5 jdk nio 用戶端建立和通信序列圖
6.為什麼要選擇 netty 架構?
netty 是業界最流行的 nio 架構之一,它的健壯性、功能、性能、可定制性和可擴充性在同類架構中都是首屈一指的,它已經得到成百上千的商用項目驗證,例如 hadoop 的 rpc 架構 avro 使用 netty 作為通信架構。很多其它業界主流的 rpc 和分布式服務架構,也使用 netty 來建構高性能的異步通信能力。
netty 的優點總結如下:
api 使用簡單,開發門檻低;
功能強大,預置了多種編解碼功能,支援多種主流協定;
定制能力強,可以通過 channelhandler 對通信架構進行靈活的擴充;
性能高,通過與其它業界主流的 nio 架構對比,netty 的綜合性能最優;
社群活躍,版本疊代周期短,發現的 bug 可以被及時修複,同時,更多的新功能會被加入;
經曆了大規模的商業應用考驗,品質得到驗證。在網際網路、大資料、網絡遊戲、企業應用、電信軟體等衆多行業得到成功商用,證明了它完全滿足不同行業的商用标準。
正是因為這些優點,netty 逐漸成為 java nio 程式設計的首選架構。
7.聽說 netty 各版本的 api 變化比較頻繁,我該如何選擇版本?
事實上,netty 各版本之間的 api 變更并沒有一些人講的那麼可怕,最大的變更就是 3.x 系列到 4.x/5.x 的變更,netty 不僅僅重構了包路徑,對于之前一直想改但是考慮到前向相容性沒改的類庫進行了優化和修改。這次變更的主要原因是 netty 脫離了 jboss 獨立發展,這對于 netty 的長遠發展是件好事。
在我看來,netty4.x 系列版本的架構和 api 設計更加合理,同時,它提供了更多新的特性。是以,我個人建議使用者可以選擇 4.x 系列版本,以免未來更新遇到困難和問題。
對于已經使用 3.x 系列版本的使用者,如果現有功能已經滿足需求,短期内暫時不需要更新。如果需要使用更多新特性和功能,建議在充分評估之後進行更新,這可能需要一些工作量。
由于 netty5 最新版本仍處于測試階段,從學習和研究角度可以試用一下,netty5 相比于 netty4 是前向相容的,是以,未來使用者更新到 netty5 會更加容易。
8.netty 和 mina 我究竟該選擇哪個?
根據我的經驗,無論選擇哪個,都是個正确的選擇。兩者各有千秋,netty 在記憶體管理方面更勝一籌,綜合性能也更優。但是,api 變更的管理和相容性做的不是太好。相比于 netty,mina 的前向相容性、内聚的可維護性功能更多,例如 jmx 的內建、性能統計、狀态機等。
建議使用者可以根據自己對兩者的熟悉程度和實際項目需求,做出最佳選擇。如果你鎖定了兩者,本身就意味着你做出了正确選擇,不需要再糾結于選擇哪個而和上司、同僚吵得面紅耳赤。
9.netty 使用簡單嗎?
netty 的基礎開發和應用非常簡單,開發一個 echo 服務端隻需要 28 行代碼,開發對應的 echo 用戶端隻需要 26 行代碼!
但是,如果你要利用它進行私有協定棧開發、http 服務端和用戶端開發等,仍然需要深入的學習 netty 的一些進階類庫和功能,了解 netty 的設計原理。隻有這樣,才能恰到好處的使用 netty,為項目和公司帶來更大的價值。
10.有沒有 netty 相關的書籍供學習和參考?
2014 年5-6 月,中國第一本學習 netty 的教材《netty 權威指南》将由電子工業出版社博文視點出版。
全書共 23 個章節,從 java io 的曆史演進講起,包括 nio 基礎入門、netty 基礎入門、netty 編解碼架構的使用和開發、udp 開發、異步檔案傳輸、基于 netty 的異步 http 協定棧開發和應用、半包解碼器的定制和使用、私有協定棧的設計和開發、行業應用、架構剖析、核心類庫的功能講解和源碼分析等。
無論你是初學者,還是 nio 高手,都能從本書中汲取營養,為掌握乃至精通 netty 提供快捷通道。
11.我是大學畢業生,正在學習 java,聽說掌握 netty 等 nio 架構找工作會相對容易一些,是真的嗎?
從我的經驗和 netty 行業應用來看,前景無限好!下面我們通過谷歌搜尋簡單看下現在市場對 netty 和 mina 的需求。
下面是我的一小部分搜尋結果:
由于搜尋結果太多,我就不一一枚舉。市場上對 netty 和 mina 的需求非常旺盛,而且相對高端,是以薪水會更高些。例如,深圳某國企開出的薪水在 20w 以上,上不封頂,這足以說明 netty 的“高大上”。
就個人而言,我無意冒犯或者貶低其它技術,但是,相比于 web 前台開發/精通 spring 架構等,精通和熟悉 netty 的人畢竟是非常少的。一個原因是異步網絡程式設計的複雜性,另一個原因是中國的 nio 程式設計正處于方興未艾階段,市場需求在逐漸增大,開始出現井噴。但是精通 nio 程式設計和具有相關經驗的人太少,導緻供需不平衡,這也是最近 netty 越來越火的一個重要原因,市場需求決定技術導向。