1.Netty 是什么?
Netty 是一個(gè)基于 JAVA NIO 類庫的異步通信框架,它的架構(gòu)特點(diǎn)是:異步非阻塞猫妙、基于事件驅(qū)動(dòng)、高性能聚凹、高可靠性和高可定制性割坠。
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ǔ)類庫,可以非常方便的實(shí)現(xiàn)私有協(xié)議棧編解碼框架的二次定制和開發(fā)稠氮;
基于職責(zé)鏈模式的 Pipeline-Handler 機(jī)制曹阔,用戶可以非常方便的對網(wǎng)絡(luò)事件進(jìn)行攔截和定制;
所有的 IO 操作都是異步的隔披,用戶可以通過 Future-Listener 機(jī)制主動(dòng) Get 結(jié)果或者由 IO 線程操作完成之后主動(dòng) Notify 結(jié)果次兆,用戶的業(yè)務(wù)線程不需要同步等待;
IP 黑白名單控制锹锰;
打印消息碼流芥炭;
流量控制和整形漓库;
性能統(tǒng)計(jì);
基于鏈路空閑事件檢測的心跳檢測
……
3.Netty 在哪些行業(yè)得到了應(yīng)用园蝠?
互聯(lián)網(wǎng)行業(yè):隨著網(wǎng)站規(guī)模的不斷擴(kuò)大渺蒿,系統(tǒng)并發(fā)訪問量也越來越高,傳統(tǒng)基于 Tomcat 等 Web 容器的垂直架構(gòu)已經(jīng)無法滿足需求彪薛,需要拆分應(yīng)用進(jìn)行服務(wù)化茂装,以提高開發(fā)和維護(hù)效率。從組網(wǎng)情況看善延,垂直的架構(gòu)拆分之后少态,系統(tǒng)采用分布式部署,各個(gè)節(jié)點(diǎn)之間需要遠(yuǎn)程服務(wù)調(diào)用易遣,高性能的 RPC 框架必不可少彼妻,Netty 作為異步高性能的通信框架,往往作為基礎(chǔ)通信組件被這些 RPC 框架使用豆茫。
典型的應(yīng)用有:阿里分布式服務(wù)框架 Dubbo 的 RPC 框架使用 Dubbo 協(xié)議進(jìn)行節(jié)點(diǎn)間通信侨歉,Dubbo 協(xié)議默認(rèn)使用 Netty 作為基礎(chǔ)通信組件,用于實(shí)現(xiàn)各進(jìn)程節(jié)點(diǎn)之間的內(nèi)部通信揩魂。它的架構(gòu)圖如下:
圖1-1 Dubbo 節(jié)點(diǎn)間調(diào)用關(guān)系圖
其中幽邓,服務(wù)提供者和服務(wù)消費(fèi)者之間,服務(wù)提供者火脉、服務(wù)消費(fèi)者和性能統(tǒng)計(jì)節(jié)點(diǎn)之間使用 Netty 進(jìn)行異步/同步通信牵舵。
除了 Dubbo 之外,淘寶的消息中間件 RocketMQ 的消息生產(chǎn)者和消息消費(fèi)者之間倦挂,也采用 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é)議棧假颇。賬號(hào)登陸服務(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é)點(diǎn)通信姜钳,它的 Netty Service 基于 Netty 框架二次封裝實(shí)現(xiàn)坦冠。
大數(shù)據(jù)計(jì)算往往采用多個(gè)計(jì)算節(jié)點(diǎn)和一個(gè)/N個(gè)匯總節(jié)點(diǎn)進(jìn)行分布式部署,各節(jié)點(diǎn)之間存在海量的數(shù)據(jù)交換哥桥。由于 Netty 的綜合性能是目前各個(gè)成熟 NIO 框架中最高的辙浑,因此,往往會(huì)被選中用作大數(shù)據(jù)各節(jié)點(diǎn)間的通信拟糕。
企業(yè)軟件:企業(yè)和 IT 集成需要 ESB判呕,Netty 對多協(xié)議支持、私有協(xié)議定制的簡潔性和高性能是 ESB RPC 框架的首選通信組件送滞。事實(shí)上侠草,很多企業(yè)總線廠商會(huì)選擇 Netty 作為基礎(chǔ)通信組件,用于企業(yè)的 IT 集成犁嗅。
通信行業(yè):Netty 的異步高性能边涕、高可靠性和高成熟度的優(yōu)點(diǎn),使它在通信行業(yè)得到了大量的應(yīng)用愧哟。
4.使用傳統(tǒng)的 Socket 開發(fā)挺簡單的奥吩,我為什么要切換到 NIO 進(jìn)行編程呢?
首先我們看下傳統(tǒng)基于同步阻塞 IO(BIO)的線程模型圖:
圖1-3 同步阻塞 IO(BIO)線程模型圖
由上圖我們可以看出蕊梧,傳統(tǒng)的同步阻塞 IO 通信存在如下幾個(gè)問題:
線程模型存在致命缺陷:一連接一線程的模型導(dǎo)致服務(wù)端無法承受大量客戶端的并發(fā)連接霞赫;
性能差:頻繁的線程上下文切換導(dǎo)致 CPU 利用效率不高;
可靠性差:由于所有的 IO 操作都是同步的肥矢,所以業(yè)務(wù)線程只要進(jìn)行 IO 操作端衰,也會(huì)存在被同步阻塞的風(fēng)險(xiǎn),這會(huì)導(dǎo)致系統(tǒng)的可靠性差甘改,依賴外部組件的處理能力和網(wǎng)絡(luò)的情況旅东。
采用非阻塞 IO(NIO)之后,同步阻塞 IO 的三個(gè)缺陷都將迎刃而解:
Nio 采用 Reactor 模式十艾,一個(gè) Reactor 線程聚合一個(gè)多路復(fù)用器 Selector抵代,它可以同時(shí)注冊、監(jiān)聽和輪詢成百上千個(gè) Channel忘嫉,一個(gè) IO 線程可以同時(shí)并發(fā)處理N個(gè)客戶端連接荤牍,線程模型優(yōu)化為1:N(N < 進(jìn)程可用的最大句柄數(shù))或者 M : N (M通常為 CPU 核數(shù) + 1, N < 進(jìn)程可用的最大句柄數(shù))庆冕;
由于 IO 線程總數(shù)有限康吵,不會(huì)存在頻繁的 IO 線程之間上下文切換和競爭,CPU 利用率高访递;
所有的 IO 操作都是異步的晦嵌,即使業(yè)務(wù)線程直接進(jìn)行 IO 操作,也不會(huì)被同步阻塞,系統(tǒng)不再依賴外部的網(wǎng)絡(luò)環(huán)境和外部應(yīng)用程序的處理性能惭载。
由于切換到 NIO 編程之后可以為系統(tǒng)帶來巨大的可靠性旱函、性能提升,所以棕兼,目前采用 NIO 進(jìn)行通信已經(jīng)逐漸成為主流陡舅。
5.為什么不直接基于 JDK 的 NIO 類庫編程呢?
我們通過 JDK NIO 服務(wù)端和客戶端的工作時(shí)序圖來回答下這個(gè)問題:
圖1-4 JDK NIO 服務(wù)端創(chuàng)建和通信序列圖
即便拋開代碼和 NIO 類庫復(fù)雜性不談伴挚,一個(gè)高性能靶衍、高可靠性的 NIO 服務(wù)端開發(fā)和維護(hù)成本都是非常高的,開發(fā)者需要具有豐富的 NIO 編程經(jīng)驗(yàn)和網(wǎng)絡(luò)維護(hù)經(jīng)驗(yàn)茎芋,很多時(shí)候甚至需要通過抓包來定位問題颅眶。也許開發(fā)出一套 NIO 程序需要 1 個(gè)月,但是它的穩(wěn)定很可能需要 1 年甚至更長的時(shí)間田弥,這也就是為什么我不建議直接使用 JDK NIO 類庫進(jìn)行通信開發(fā)的一個(gè)重要原因涛酗。
下面再一起看下 JDK NIO 客戶端的通信時(shí)序圖:它同樣非常復(fù)雜。
圖1-5 JDK NIO 客戶端創(chuàng)建和通信序列圖
6.為什么要選擇 Netty 框架偷厦?
Netty 是業(yè)界最流行的 NIO 框架之一商叹,它的健壯性、功能只泼、性能剖笙、可定制性和可擴(kuò)展性在同類框架中都是首屈一指的,它已經(jīng)得到成百上千的商用項(xiàng)目驗(yàn)證请唱,例如 Hadoop 的 RPC 框架 Avro 使用 Netty 作為通信框架弥咪。很多其它業(yè)界主流的 RPC 和分布式服務(wù)框架,也使用 Netty 來構(gòu)建高性能的異步通信能力十绑。
Netty 的優(yōu)點(diǎn)總結(jié)如下:
API 使用簡單聚至,開發(fā)門檻低;
功能強(qiáng)大本橙,預(yù)置了多種編解碼功能扳躬,支持多種主流協(xié)議;
定制能力強(qiáng)甚亭,可以通過 ChannelHandler 對通信框架進(jìn)行靈活的擴(kuò)展贷币;
性能高,通過與其它業(yè)界主流的 NIO 框架對比狂鞋,Netty 的綜合性能最優(yōu)片择;
社區(qū)活躍潜的,版本迭代周期短骚揍,發(fā)現(xiàn)的 BUG 可以被及時(shí)修復(fù),同時(shí),更多的新功能會(huì)被加入信不;
經(jīng)歷了大規(guī)模的商業(yè)應(yīng)用考驗(yàn)嘲叔,質(zhì)量得到驗(yàn)證。在互聯(lián)網(wǎng)抽活、大數(shù)據(jù)硫戈、網(wǎng)絡(luò)游戲、企業(yè)應(yīng)用下硕、電信軟件等眾多行業(yè)得到成功商用丁逝,證明了它完全滿足不同行業(yè)的商用標(biāo)準(zhǔn)。
正是因?yàn)檫@些優(yōu)點(diǎn)梭姓,Netty 逐漸成為 Java NIO 編程的首選框架霜幼。
7.聽說 Netty 各版本的 API 變化比較頻繁,我該如何選擇版本誉尖?
事實(shí)上罪既,Netty 各版本之間的 API 變更并沒有一些人講的那么可怕,最大的變更就是 3.X 系列到 4.X/5.X 的變更铡恕,Netty 不僅僅重構(gòu)了包路徑琢感,對于之前一直想改但是考慮到前向兼容性沒改的類庫進(jìn)行了優(yōu)化和修改。這次變更的主要原因是 Netty 脫離了 Jboss 獨(dú)立發(fā)展探熔,這對于 Netty 的長遠(yuǎn)發(fā)展是件好事驹针。
在我看來,Netty4.X 系列版本的架構(gòu)和 API 設(shè)計(jì)更加合理祭刚,同時(shí)牌捷,它提供了更多新的特性。因此涡驮,我個(gè)人建議用戶可以選擇 4.X 系列版本暗甥,以免未來升級遇到困難和問題。
對于已經(jīng)使用 3.X 系列版本的用戶捉捅,如果現(xiàn)有功能已經(jīng)滿足需求撤防,短期內(nèi)暫時(shí)不需要升級。如果需要使用更多新特性和功能棒口,建議在充分評估之后進(jìn)行升級寄月,這可能需要一些工作量。
由于 Netty5 最新版本仍處于測試階段无牵,從學(xué)習(xí)和研究角度可以試用一下漾肮,Netty5 相比于 Netty4 是前向兼容的,因此茎毁,未來用戶升級到 Netty5 會(huì)更加容易克懊。
8.Netty 和 Mina 我究竟該選擇哪個(gè)忱辅?
根據(jù)我的經(jīng)驗(yàn),無論選擇哪個(gè)谭溉,都是個(gè)正確的選擇墙懂。兩者各有千秋,Netty 在內(nèi)存管理方面更勝一籌扮念,綜合性能也更優(yōu)损搬。但是,API 變更的管理和兼容性做的不是太好柜与。相比于 Netty巧勤,Mina 的前向兼容性、內(nèi)聚的可維護(hù)性功能更多弄匕,例如 JMX 的集成踢关、性能統(tǒng)計(jì)、狀態(tài)機(jī)等粘茄。
建議用戶可以根據(jù)自己對兩者的熟悉程度和實(shí)際項(xiàng)目需求签舞,做出最佳選擇。如果你鎖定了兩者柒瓣,本身就意味著你做出了正確選擇儒搭,不需要再糾結(jié)于選擇哪個(gè)而和領(lǐng)導(dǎo)、同事吵得面紅耳赤芙贫。
9.Netty 使用簡單嗎搂鲫?
Netty 的基礎(chǔ)開發(fā)和應(yīng)用非常簡單,開發(fā)一個(gè) Echo 服務(wù)端只需要 28 行代碼磺平,開發(fā)對應(yīng)的 Echo 客戶端只需要 26 行代碼魂仍!
但是,如果你要利用它進(jìn)行私有協(xié)議棧開發(fā)拣挪、HTTP 服務(wù)端和客戶端開發(fā)等擦酌,仍然需要深入的學(xué)習(xí) Netty 的一些高級類庫和功能,了解 Netty 的設(shè)計(jì)原理菠劝。只有這樣赊舶,才能恰到好處的使用 Netty,為項(xiàng)目和公司帶來更大的價(jià)值赶诊。
10.有沒有 Netty 相關(guān)的書籍供學(xué)習(xí)和參考笼平?
2014 年5-6 月,中國第一本學(xué)習(xí) Netty 的教材《Netty 權(quán)威指南》將由電子工業(yè)出版社博文視點(diǎn)出版舔痪。
全書共 23 個(gè)章節(jié)寓调,從 JAVA IO 的歷史演進(jìn)講起,包括 NIO 基礎(chǔ)入門锄码、Netty 基礎(chǔ)入門夺英、Netty 編解碼框架的使用和開發(fā)鸠珠、UDP 開發(fā)、異步文件傳輸秋麸、基于 Netty 的異步 HTTP 協(xié)議棧開發(fā)和應(yīng)用、半包解碼器的定制和使用炬太、私有協(xié)議棧的設(shè)計(jì)和開發(fā)灸蟆、行業(yè)應(yīng)用、架構(gòu)剖析亲族、核心類庫的功能講解和源碼分析等炒考。
無論你是初學(xué)者,還是 NIO 高手霎迫,都能從本書中汲取營養(yǎng)斋枢,為掌握乃至精通 Netty 提供快捷通道。
歡迎加入技術(shù)QQ群:364595326