【說明】本文原載于碼農(nóng) IO(manong.io)官方微信 developerWorks,轉(zhuǎn)載、引用請注明出處及作者。
1.Netty 是什么?
Netty 是一個基于 JAVA NIO 類庫的異步通信框架,它的架構(gòu)特點是:異步非阻塞、基于事件驅(qū)動、高性能、高可靠性和高可定制性。
2.使用 Netty 能夠做什么?
開發(fā)異步、非阻塞的 TCP 網(wǎng)絡(luò)應(yīng)用程序;
開發(fā)異步、非阻塞的 UDP 網(wǎng)絡(luò)應(yīng)用程序;
開發(fā)異步文件傳輸應(yīng)用程序;
開發(fā)異步 HTTP 服務(wù)端和客戶端應(yīng)用程序;
提供對多種編解碼框架的集成,包括谷歌的 Protobuf、Jbossmarshalling、Java 序列化、壓縮編解碼、XML 解碼、字符串編解碼等,這些編解碼框架可以被用戶直接使用;
提供形式多樣的編解碼基礎(chǔ)類庫,可以非常方便的實現(xiàn)私有協(xié)議棧編解碼框架的二次定制和開發(fā);
基于職責(zé)鏈模式的 Pipeline-Handler 機制,用戶可以非常方便的對網(wǎng)絡(luò)事件進(jìn)行攔截和定制;
所有的 IO 操作都是異步的,用戶可以通過 Future-Listener 機制主動 Get 結(jié)果或者由 IO 線程操作完成之后主動 Notify 結(jié)果,用戶的業(yè)務(wù)線程不需要同步等待;
IP 黑白名單控制;
打印消息碼流;
流量控制和整形;
性能統(tǒng)計;
基于鏈路空閑事件檢測的心跳檢測
……
3.Netty 在哪些行業(yè)得到了應(yīng)用?
互聯(lián)網(wǎng)行業(yè):隨著網(wǎng)站規(guī)模的不斷擴大,系統(tǒng)并發(fā)訪問量也越來越高,傳統(tǒng)基于 Tomcat 等 Web 容器的垂直架構(gòu)已經(jīng)無法滿足需求,需要拆分應(yīng)用進(jìn)行服務(wù)化,以提高開發(fā)和維護(hù)效率。從組網(wǎng)情況看,垂直的架構(gòu)拆分之后,系統(tǒng)采用分布式部署,各個節(jié)點之間需要遠(yuǎn)程服務(wù)調(diào)用,高性能的 RPC 框架必不可少,Netty 作為異步高性能的通信框架,往往作為基礎(chǔ)通信組件被這些 RPC 框架使用。
典型的應(yīng)用有:阿里分布式服務(wù)框架 Dubbo 的 RPC 框架使用 Dubbo 協(xié)議進(jìn)行節(jié)點間通信,Dubbo 協(xié)議默認(rèn)使用 Netty 作為基礎(chǔ)通信組件,用于實現(xiàn)各進(jìn)程節(jié)點之間的內(nèi)部通信。它的架構(gòu)圖如下:
圖1-1 Dubbo 節(jié)點間調(diào)用關(guān)系圖
其中,服務(wù)提供者和服務(wù)消費者之間,服務(wù)提供者、服務(wù)消費者和性能統(tǒng)計節(jié)點之間使用 Netty 進(jìn)行異步/同步通信。
除了 Dubbo 之外,淘寶的消息中間件 RocketMQ 的消息生產(chǎn)者和消息消費者之間,也采用 Netty 進(jìn)行高性能、異步通信。
除了阿里系和淘寶系之外,很多其它的大型互聯(lián)網(wǎng)公司或者電商內(nèi)部也已經(jīng)大量使用 Netty 構(gòu)建高性能、分布式的網(wǎng)絡(luò)服務(wù)器。
游戲行業(yè):無論是手游服務(wù)端、還是大型的網(wǎng)絡(luò)游戲,Java 語言得到了越來越廣泛的應(yīng)用。Netty 作為高性能的基礎(chǔ)通信組件,它本身提供了 TCP/UDP 和 HTTP 協(xié)議棧,非常方便定制和開發(fā)私有協(xié)議棧。賬號登陸服務(wù)器、地圖服務(wù)器之間可以方便的通過 Netty 進(jìn)行高性能的通信,架構(gòu)示意圖如下:
圖1-2 Netty 在游戲服務(wù)器架構(gòu)中的應(yīng)用
大數(shù)據(jù)領(lǐng)域:經(jīng)典的 Hadoop 的高性能通信和序列化組件 Avro 的 RPC 框架,默認(rèn)采用 Netty 進(jìn)行跨節(jié)點通信,它的 Netty Service 基于 Netty 框架二次封裝實現(xiàn)。
大數(shù)據(jù)計算往往采用多個計算節(jié)點和一個/N個匯總節(jié)點進(jìn)行分布式部署,各節(jié)點之間存在海量的數(shù)據(jù)交換。由于 Netty 的綜合性能是目前各個成熟 NIO 框架中最高的,因此,往往會被選中用作大數(shù)據(jù)各節(jié)點間的通信。
企業(yè)軟件:企業(yè)和 IT 集成需要 ESB,Netty 對多協(xié)議支持、私有協(xié)議定制的簡潔性和高性能是 ESB RPC 框架的首選通信組件。事實上,很多企業(yè)總線廠商會選擇 Netty 作為基礎(chǔ)通信組件,用于企業(yè)的 IT 集成。
通信行業(yè):Netty 的異步高性能、高可靠性和高成熟度的優(yōu)點,使它在通信行業(yè)得到了大量的應(yīng)用。
4.使用傳統(tǒng)的 Socket 開發(fā)挺簡單的,我為什么要切換到 NIO 進(jìn)行編程呢?
首先我們看下傳統(tǒng)基于同步阻塞 IO(BIO)的線程模型圖:
圖1-3 同步阻塞 IO(BIO)線程模型圖
由上圖我們可以看出,傳統(tǒng)的同步阻塞 IO 通信存在如下幾個問題:
線程模型存在致命缺陷:一連接一線程的模型導(dǎo)致服務(wù)端無法承受大量客戶端的并發(fā)連接;
性能差:頻繁的線程上下文切換導(dǎo)致 CPU 利用效率不高;
可靠性差:由于所有的 IO 操作都是同步的,所以業(yè)務(wù)線程只要進(jìn)行 IO 操作,也會存在被同步阻塞的風(fēng)險,這會導(dǎo)致系統(tǒng)的可靠性差,依賴外部組件的處理能力和網(wǎng)絡(luò)的情況。
采用非阻塞 IO(NIO)之后,同步阻塞 IO 的三個缺陷都將迎刃而解:
Nio 采用 Reactor 模式,一個 Reactor 線程聚合一個多路復(fù)用器 Selector,它可以同時注冊、監(jiān)聽和輪詢成百上千個 Channel,一個 IO 線程可以同時并發(fā)處理N個客戶端連接,線程模型優(yōu)化為1:N(N < 進(jìn)程可用的最大句柄數(shù))或者 M : N (M通常為 CPU 核數(shù) + 1, N < 進(jìn)程可用的最大句柄數(shù));
由于 IO 線程總數(shù)有限,不會存在頻繁的 IO 線程之間上下文切換和競爭,CPU 利用率高;
所有的 IO 操作都是異步的,即使業(yè)務(wù)線程直接進(jìn)行 IO 操作,也不會被同步阻塞,系統(tǒng)不再依賴外部的網(wǎng)絡(luò)環(huán)境和外部應(yīng)用程序的處理性能。
由于切換到 NIO 編程之后可以為系統(tǒng)帶來巨大的可靠性、性能提升,所以,目前采用 NIO 進(jìn)行通信已經(jīng)逐漸成為主流。
5.為什么不直接基于 JDK 的 NIO 類庫編程呢?
我們通過 JDK NIO 服務(wù)端和客戶端的工作時序圖來回答下這個問題:
圖1-4 JDK NIO 服務(wù)端創(chuàng)建和通信序列圖
即便拋開代碼和 NIO 類庫復(fù)雜性不談,一個高性能、高可靠性的 NIO 服務(wù)端開發(fā)和維護(hù)成本都是非常高的,開發(fā)者需要具有豐富的 NIO 編程經(jīng)驗和網(wǎng)絡(luò)維護(hù)經(jīng)驗,很多時候甚至需要通過抓包來定位問題。也許開發(fā)出一套 NIO 程序需要 1 個月,但是它的穩(wěn)定很可能需要 1 年甚至更長的時間,這也就是為什么我不建議直接使用 JDK NIO 類庫進(jìn)行通信開發(fā)的一個重要原因。
下面再一起看下 JDK NIO 客戶端的通信時序圖:它同樣非常復(fù)雜。
圖1-5 JDK NIO 客戶端創(chuàng)建和通信序列圖
6.為什么要選擇 Netty 框架?
Netty 是業(yè)界最流行的 NIO 框架之一,它的健壯性、功能、性能、可定制性和可擴展性在同類框架中都是首屈一指的,它已經(jīng)得到成百上千的商用項目驗證,例如 Hadoop 的 RPC 框架 Avro 使用 Netty 作為通信框架。很多其它業(yè)界主流的 RPC 和分布式服務(wù)框架,也使用 Netty 來構(gòu)建高性能的異步通信能力。
Netty 的優(yōu)點總結(jié)如下:
API 使用簡單,開發(fā)門檻低;
功能強大,預(yù)置了多種編解碼功能,支持多種主流協(xié)議;
定制能力強,可以通過 ChannelHandler 對通信框架進(jìn)行靈活的擴展;
性能高,通過與其它業(yè)界主流的 NIO 框架對比,Netty 的綜合性能最優(yōu);
社區(qū)活躍,版本迭代周期短,發(fā)現(xiàn)的 BUG 可以被及時修復(fù),同時,更多的新功能會被加入;
經(jīng)歷了大規(guī)模的商業(yè)應(yīng)用考驗,質(zhì)量得到驗證。在互聯(lián)網(wǎng)、大數(shù)據(jù)、網(wǎng)絡(luò)游戲、企業(yè)應(yīng)用、電信軟件等眾多行業(yè)得到成功商用,證明了它完全滿足不同行業(yè)的商用標(biāo)準(zhǔn)。
正是因為這些優(yōu)點,Netty 逐漸成為 Java NIO 編程的首選框架。
7.聽說 Netty 各版本的 API 變化比較頻繁,我該如何選擇版本?
事實上,Netty 各版本之間的 API 變更并沒有一些人講的那么可怕,最大的變更就是 3.X 系列到 4.X/5.X 的變更,Netty 不僅僅重構(gòu)了包路徑,對于之前一直想改但是考慮到前向兼容性沒改的類庫進(jìn)行了優(yōu)化和修改。這次變更的主要原因是 Netty 脫離了 Jboss 獨立發(fā)展,這對于 Netty 的長遠(yuǎn)發(fā)展是件好事。
在我看來,Netty4.X 系列版本的架構(gòu)和 API 設(shè)計更加合理,同時,它提供了更多新的特性。因此,我個人建議用戶可以選擇 4.X 系列版本,以免未來升級遇到困難和問題。
對于已經(jīng)使用 3.X 系列版本的用戶,如果現(xiàn)有功能已經(jīng)滿足需求,短期內(nèi)暫時不需要升級。如果需要使用更多新特性和功能,建議在充分評估之后進(jìn)行升級,這可能需要一些工作量。
由于 Netty5 最新版本仍處于測試階段,從學(xué)習(xí)和研究角度可以試用一下,Netty5 相比于 Netty4 是前向兼容的,因此,未來用戶升級到 Netty5 會更加容易。
8.Netty 和 Mina 我究竟該選擇哪個?
根據(jù)我的經(jīng)驗,無論選擇哪個,都是個正確的選擇。兩者各有千秋,Netty 在內(nèi)存管理方面更勝一籌,綜合性能也更優(yōu)。但是,API 變更的管理和兼容性做的不是太好。相比于 Netty,Mina 的前向兼容性、內(nèi)聚的可維護(hù)性功能更多,例如 JMX 的集成、性能統(tǒng)計、狀態(tài)機等。
建議用戶可以根據(jù)自己對兩者的熟悉程度和實際項目需求,做出最佳選擇。如果你鎖定了兩者,本身就意味著你做出了正確選擇,不需要再糾結(jié)于選擇哪個而和領(lǐng)導(dǎo)、同事吵得面紅耳赤。
9.Netty 使用簡單嗎?
Netty 的基礎(chǔ)開發(fā)和應(yīng)用非常簡單,開發(fā)一個 Echo 服務(wù)端只需要 28 行代碼,開發(fā)對應(yīng)的 Echo 客戶端只需要 26 行代碼!
但是,如果你要利用它進(jìn)行私有協(xié)議棧開發(fā)、HTTP 服務(wù)端和客戶端開發(fā)等,仍然需要深入的學(xué)習(xí) Netty 的一些高級類庫和功能,了解 Netty 的設(shè)計原理。只有這樣,才能恰到好處的使用 Netty,為項目和公司帶來更大的價值。
10.有沒有 Netty 相關(guān)的書籍供學(xué)習(xí)和參考?
2014 年5-6 月,中國第一本學(xué)習(xí) Netty 的教材《Netty 權(quán)威指南》將由電子工業(yè)出版社博文視點出版。
全書共 23 個章節(jié),從 JAVA IO 的歷史演進(jìn)講起,包括 NIO 基礎(chǔ)入門、Netty 基礎(chǔ)入門、Netty 編解碼框架的使用和開發(fā)、UDP 開發(fā)、異步文件傳輸、基于 Netty 的異步 HTTP 協(xié)議棧開發(fā)和應(yīng)用、半包解碼器的定制和使用、私有協(xié)議棧的設(shè)計和開發(fā)、行業(yè)應(yīng)用、架構(gòu)剖析、核心類庫的功能講解和源碼分析等。
無論你是初學(xué)者,還是 NIO 高手,都能從本書中汲取營養(yǎng),為掌握乃至精通 Netty 提供快捷通道。
11.我是大學(xué)畢業(yè)生,正在學(xué)習(xí) Java,聽說掌握 Netty 等 NIO 框架找工作會相對容易一些,是真的嗎?
從我的經(jīng)驗和 Netty 行業(yè)應(yīng)用來看,前景無限好!下面我們通過谷歌搜索簡單看下現(xiàn)在市場對 Netty 和 Mina 的需求。
下面是我的一小部分搜索結(jié)果:
由于搜索結(jié)果太多,我就不一一枚舉。市場上對 Netty 和 Mina 的需求非常旺盛,而且相對高端,所以薪水會更高些。例如,深圳某國企開出的薪水在 20W 以上,上不封頂,這足以說明 Netty 的“高大上”。
就個人而言,我無意冒犯或者貶低其它技術(shù),但是,相比于 WEB 前臺開發(fā)/精通 Spring 框架等,精通和熟悉 Netty 的人畢竟是非常少的。一個原因是異步網(wǎng)絡(luò)編程的復(fù)雜性,另一個原因是中國的 NIO 編程正處于方興未艾階段,市場需求在逐漸增大,開始出現(xiàn)井噴。但是精通 NIO 編程和具有相關(guān)經(jīng)驗的人太少,導(dǎo)致供需不平衡,這也是最近 Netty 越來越火的一個重要原因,市場需求決定技術(shù)導(dǎo)向。
【作者簡介】李林鋒:現(xiàn)就職于某世界五百強通信公司,擁有 5 年 NIO 設(shè)計、開發(fā)和維護(hù)經(jīng)驗,長期從事高性能通信軟件的架構(gòu)設(shè)計和開發(fā)工作,設(shè)計的多款平臺軟件已經(jīng)成功在N個商業(yè)局點穩(wěn)定運行多年。
聯(lián)系方式:新浪微博:@Nettying 郵箱:neu_lilinfeng@sina.com