Netty

第 1 章 Netty 介紹和應(yīng)用場(chǎng)景

1.2 Netty 的介紹

  1. Netty 是由 JBOSS 提供的一個(gè) Java 開源框架,現(xiàn)為 Github 上的獨(dú)立項(xiàng)目。
  2. Netty 是一個(gè)異步的、基于事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,用以快速開發(fā)高性能、高可靠性的網(wǎng)絡(luò) IO 程序。
image.png
  1. Netty 主要針對(duì)在 TCP 協(xié)議下,面向 Clients 端的高并發(fā)應(yīng)用,或者 Peer-to-Peer 場(chǎng)景下的大量數(shù)據(jù)持續(xù)傳輸?shù)?應(yīng)用。

  2. Netty 本質(zhì)是一個(gè) NIO 框架,適用于服務(wù)器通訊相關(guān)的多種應(yīng)用場(chǎng)景


    image.png
  3. 要透徹理解 Netty , 需要先學(xué)習(xí) NIO , 這樣我們才能閱讀 Netty 的源碼。

1.3 Netty 的應(yīng)用場(chǎng)景

1.3.1互聯(lián)網(wǎng)行業(yè)

  1. 互聯(lián)網(wǎng)行業(yè):在分布式系統(tǒng)中,各個(gè)節(jié)點(diǎn)之間需要遠(yuǎn)程服務(wù)調(diào)用,高性能的 RPC 框架必不可少,Netty 作為 異步高性能的通信框架,往往作為基礎(chǔ)通信組件被這些 RPC 框架使用。
  2. 典型的應(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)部通信
    1.3.2游戲行業(yè)
  3. 無(wú)論是手游服務(wù)端還是大型的網(wǎng)絡(luò)游戲,Java 語(yǔ)言得到了越來(lái)越廣泛的應(yīng)用
  4. Netty 作為高性能的基礎(chǔ)通信組件,提供了 TCP/UDP 和 HTTP 協(xié)議棧,方便定制和開發(fā)私有協(xié)議棧,賬號(hào)登 錄服務(wù)器
  5. 地圖服務(wù)器之間可以方便的通過(guò) Netty 進(jìn)行高性能的通信
    1.3.3大數(shù)據(jù)領(lǐng)域
  6. 經(jīng)典的 Hadoop 的高性能通信和序列化組件 Avro 的 RPC 框架,默認(rèn)采用 Netty 進(jìn)行跨界點(diǎn)通信
  7. 它的 Netty Service 基于 Netty 框架二次封裝實(shí)現(xiàn)。

第 5 章 Netty 高性能架構(gòu)設(shè)計(jì)

5.1 線程模型基本介紹

  1. 不同的線程模式,對(duì)程序的性能有很大影響,為了搞清 Netty 線程模式,我們來(lái)系統(tǒng)的講解下 各個(gè)線程模式, 最后看看 Netty 線程模型有什么優(yōu)越性。
  2. 目前存在的線程模型有: 傳統(tǒng)阻塞 I/O 服務(wù)模型 Reactor 模式
  3. 根據(jù) Reactor 的數(shù)量和處理資源池線程的數(shù)量不同,
    有 3 種典型的實(shí)現(xiàn)
    單 Reactor 單線程;
    單 Reactor 多線程;
    主從 Reactor 多線程
  4. Netty 線程模式(Netty 主要基于主從 Reactor 多線程模型做了一定的改進(jìn),其中主從 Reactor 多線程模型有多 個(gè) Reactor)

5.2 傳統(tǒng)阻塞 I/O 服務(wù)模型

5.2.1工作原理圖

  1. 黃色的框表示對(duì)象, 藍(lán)色的框表示線程
  2. 白色的框表示方法(API)

5.2.2模型特點(diǎn)

  1. 采用阻塞 IO 模式獲取輸入的數(shù)據(jù)
  2. 每個(gè)連接都需要獨(dú)立的線程完成數(shù)據(jù)的輸入,業(yè)務(wù)處理, 數(shù)據(jù)返回

5.2.3問(wèn)題分析

  1. 當(dāng)并發(fā)數(shù)很大,就會(huì)創(chuàng)建大量的線程,占用很大系統(tǒng)資源
  2. 連接創(chuàng)建后,如果當(dāng)前線程暫時(shí)沒有數(shù)據(jù)可讀,該線程 會(huì)阻塞在 read 操作,造成線程資源浪費(fèi).


    image.png

5.3 Reactor 模式

5.3.1針對(duì)傳統(tǒng)阻塞 I/O 服務(wù)模型的 2 個(gè)缺點(diǎn),解決方案:

  1. 基于 I/O 復(fù)用模型:多個(gè)連接共用一個(gè)阻塞對(duì)象,應(yīng)用程序只需要在一個(gè)阻塞對(duì)象等待,無(wú)需阻塞等待所有連 接。當(dāng)某個(gè)連接有新的數(shù)據(jù)可以處理時(shí),操作系統(tǒng)通知應(yīng)用程序,線程從阻塞狀態(tài)返回,開始進(jìn)行業(yè)務(wù)處理
    Reactor 對(duì)應(yīng)的叫法: 1. 反應(yīng)器模式 2. 分發(fā)者模式(Dispatcher) 3. 通知者模式(notifier)
  2. 基于線程池復(fù)用線程資源:不必再為每個(gè)連接創(chuàng)建線程,將連接完成后的業(yè)務(wù)處理任務(wù)分配給線程進(jìn)行處理, 一個(gè)線程可以處理多個(gè)連接的業(yè)務(wù)。


    image.png

5.3.2I/O 復(fù)用結(jié)合線程池,就是 Reactor 模式基本設(shè)計(jì)思想,如圖

image.png

? 對(duì)上圖說(shuō)明:

  1. Reactor 模式通過(guò)一個(gè)或多個(gè)輸入同時(shí)傳遞給服務(wù)處理器的模式(基于事件驅(qū)動(dòng)) 。
  2. 服務(wù)器端程序處理傳入的多個(gè)請(qǐng)求,并將它們同步分派到相應(yīng)的處理線程, 因此 Reactor 模式也叫 Dispatcher 模式 。
  3. Reactor 模式使用 IO 復(fù)用監(jiān)聽事件, 收到事件后,分發(fā)給某個(gè)線程(進(jìn)程), 這點(diǎn)就是網(wǎng)絡(luò)服務(wù)器高并發(fā)處理關(guān)鍵。

5.3.3Reactor 模式中 核心組成:

  1. Reactor:Reactor 在一個(gè)單獨(dú)的線程中運(yùn)行,負(fù)責(zé)監(jiān)聽和分發(fā)事件,分發(fā)給適當(dāng)?shù)奶幚沓绦騺?lái)對(duì) IO 事件做出 反應(yīng)。 它就像公司的電話接線員,它接聽來(lái)自客戶的電話并將線路轉(zhuǎn)移到適當(dāng)?shù)穆?lián)系人;
  2. Handlers:處理程序執(zhí)行 I/O 事件要完成的實(shí)際事件,類似于客戶想要與之交談的公司中的實(shí)際官員。Reactor 通過(guò)調(diào)度適當(dāng)?shù)奶幚沓绦騺?lái)響應(yīng) I/O 事件,處理程序執(zhí)行非阻塞操作。

5.3.4Reactor 模式分類:

根據(jù) Reactor 的數(shù)量和處理資源池線程的數(shù)量不同,有 3 種典型的實(shí)現(xiàn)

  1. 單 Reactor 單線程
  2. 單 Reactor 多線程
  3. 主從 Reactor 多線程

5.4 單 Reactor 單線程

原理圖,并使用 NIO 群聊系統(tǒng)驗(yàn)證


image.png

5.4.1方案說(shuō)明:

  1. Select 是前面 I/O 復(fù)用模型介紹的標(biāo)準(zhǔn)網(wǎng)絡(luò)編程 API,可以實(shí)現(xiàn)應(yīng)用程序通過(guò)一個(gè)阻塞對(duì)象監(jiān)聽多路連接請(qǐng)求
  2. Reactor 對(duì)象通過(guò) Select 監(jiān)控客戶端請(qǐng)求事件,收到事件后通過(guò) Dispatch 進(jìn)行分發(fā)
  3. 如果是建立連接請(qǐng)求事件,則由 Acceptor 通過(guò) Accept 處理連接請(qǐng)求,然后創(chuàng)建一個(gè) Handler 對(duì)象處理連接 完成后的后續(xù)業(yè)務(wù)處理
  4. 如果不是建立連接事件,則 Reactor 會(huì)分發(fā)調(diào)用連接對(duì)應(yīng)的 Handler 來(lái)響應(yīng)
  5. Handler 會(huì)完成 Read→業(yè)務(wù)處理→Send 的完整業(yè)務(wù)流程
    結(jié)合實(shí)例:服務(wù)器端用一個(gè)線程通過(guò)多路復(fù)用搞定所有的 IO 操作(包括連接,讀、寫等),編碼簡(jiǎn)單,清晰明了, 但是如果客戶端連接數(shù)量較多,將無(wú)法支撐,前面的 NIO 案例就屬于這種模型。

5.4.2方案優(yōu)缺點(diǎn)分析:

  1. 優(yōu)點(diǎn):模型簡(jiǎn)單,沒有多線程、進(jìn)程通信、競(jìng)爭(zhēng)的問(wèn)題,全部都在一個(gè)線程中完成
  2. 缺點(diǎn):性能問(wèn)題,只有一個(gè)線程,無(wú)法完全發(fā)揮多核 CPU 的性能。Handler 在處理某個(gè)連接上的業(yè)務(wù)時(shí),整 個(gè)進(jìn)程無(wú)法處理其他連接事件,很容易導(dǎo)致性能瓶頸
  3. 缺點(diǎn):可靠性問(wèn)題,線程意外終止,或者進(jìn)入死循環(huán),會(huì)導(dǎo)致整個(gè)系統(tǒng)通信模塊不可用,不能接收和處理外部 消息,造成節(jié)點(diǎn)故障
  4. 使用場(chǎng)景:客戶端的數(shù)量有限,業(yè)務(wù)處理非??焖?,比如 Redis 在業(yè)務(wù)處理的時(shí)間復(fù)雜度 O(1) 的情況

5.5 單 Reactor 多線程

5.5.1原理圖

image.png

5.5.2對(duì)上圖的小結(jié)

  1. Reactor 對(duì)象通過(guò) select 監(jiān)控客戶端請(qǐng)求 事件, 收到事件后,通過(guò) dispatch 進(jìn)行分發(fā)
  2. 如果建立連接請(qǐng)求, 則右 Acceptor 通過(guò) accept 處理連接請(qǐng)求, 然后創(chuàng)建一個(gè) Handler 對(duì)象處理完成連接后的各種事件
  3. 如果不是連接請(qǐng)求,則由 reactor 分發(fā)調(diào)用連接對(duì)應(yīng)的 handler 來(lái)處理
  4. handler 只負(fù)責(zé)響應(yīng)事件,不做具體的業(yè)務(wù)處理, 通過(guò) read 讀取數(shù)據(jù)后,會(huì)分發(fā)給后面的 worker 線程池的某個(gè) 線程處理業(yè)務(wù)
  5. worker 線程池會(huì)分配獨(dú)立線程完成真正的業(yè)務(wù),并將結(jié)果返回給 handler
  6. handler 收到響應(yīng)后,通過(guò) send 將結(jié)果返回給 client

5.5.3方案優(yōu)缺點(diǎn)分析:

  1. 優(yōu)點(diǎn):可以充分的利用多核 cpu 的處理能力
  2. 缺點(diǎn):多線程數(shù)據(jù)共享和訪問(wèn)比較復(fù)雜, reactor 處理所有的事件的監(jiān)聽和響應(yīng),在單線程運(yùn)行, 在高并發(fā)場(chǎng) 景容易出現(xiàn)性能瓶頸.

5.6 主從 Reactor 多線程

5.6.1工作原理圖

針對(duì)單 Reactor 多線程模型中,Reactor 在單線程中運(yùn)行,高并發(fā)場(chǎng)景下容易成為性能瓶頸,可以讓 Reactor 在 多線程中運(yùn)行


image.png

5.6.2上圖的方案說(shuō)明

  1. Reactor 主線程 MainReactor 對(duì)象通過(guò) select 監(jiān)聽連接事件, 收到事件后,通過(guò) Acceptor 處理連接事件
  2. 當(dāng) Acceptor 處理連接事件后,MainReactor 將連接分配給 SubReactor
  3. subreactor 將連接加入到連接隊(duì)列進(jìn)行監(jiān)聽,并創(chuàng)建 handler 進(jìn)行各種事件處理
  4. 當(dāng)有新事件發(fā)生時(shí), subreactor 就會(huì)調(diào)用對(duì)應(yīng)的 handler 處理
  5. handler 通過(guò) read 讀取數(shù)據(jù),分發(fā)給后面的 worker 線程處理
  6. worker 線程池分配獨(dú)立的 worker 線程進(jìn)行業(yè)務(wù)處理,并返回結(jié)果
  7. handler 收到響應(yīng)的結(jié)果后,再通過(guò) send 將結(jié)果返回給 client
  8. Reactor 主線程可以對(duì)應(yīng)多個(gè) Reactor 子線程, 即 MainRecator 可以關(guān)聯(lián)多個(gè) SubReactor

5.6.3Scalable IO in Java 對(duì) Multiple Reactors 的原理圖解:

image.png

5.6.4方案優(yōu)缺點(diǎn)說(shuō)明:

  1. 優(yōu)點(diǎn):父線程與子線程的數(shù)據(jù)交互簡(jiǎn)單職責(zé)明確,父線程只需要接收新連接,子線程完成后續(xù)的業(yè)務(wù)處理。
  2. 優(yōu)點(diǎn):父線程與子線程的數(shù)據(jù)交互簡(jiǎn)單,Reactor 主線程只需要把新連接傳給子線程,子線程無(wú)需返回?cái)?shù)據(jù)。
  3. 缺點(diǎn):編程復(fù)雜度較高
  4. 結(jié)合實(shí)例:這種模型在許多項(xiàng)目中廣泛使用,包括 Nginx 主從 Reactor 多進(jìn)程模型,Memcached 主從多線程, Netty 主從多線程模型的支持

5.7 Reactor 模式小結(jié)

5.7.13 種模式用生活案例來(lái)理解

  1. 單 Reactor 單線程,前臺(tái)接待員和服務(wù)員是同一個(gè)人,全程為顧客服
  2. 單 Reactor 多線程,1 個(gè)前臺(tái)接待員,多個(gè)服務(wù)員,接待員只負(fù)責(zé)接待
  3. 主從 Reactor 多線程,多個(gè)前臺(tái)接待員,多個(gè)服務(wù)生

5.7.2 Reactor 模式具有如下的優(yōu)點(diǎn):

  1. 響應(yīng)快,不必為單個(gè)同步時(shí)間所阻塞,雖然 Reactor 本身依然是同步的
  2. 可以最大程度的避免復(fù)雜的多線程及同步問(wèn)題,并且避免了多線程/進(jìn)程的切換開銷
  3. 擴(kuò)展性好,可以方便的通過(guò)增加 Reactor 實(shí)例個(gè)數(shù)來(lái)充分利用 CPU 資源
  4. 復(fù)用性好,Reactor 模型本身與具體事件處理邏輯無(wú)關(guān),具有很高的復(fù)用性
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 原生 NIO 存在的問(wèn)題:NIO 的類庫(kù)和 API 繁雜,使用麻煩:需要熟練掌握 Selector、ServerS...
    dev_winner閱讀 561評(píng)論 0 3
  • 本文基于 Netty 4.1 展開介紹相關(guān)理論模型,使用場(chǎng)景,基本組件、整體架構(gòu),知其然且知其所以然,希望給大家在...
    賈永超閱讀 210評(píng)論 0 0
  • 1.Netty 是什么? Netty 是 一個(gè)異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架,用于快速開發(fā)可維護(hù)的高性能協(xié)議服務(wù) ...
    Java__JJ閱讀 998評(píng)論 0 2
  • 久違的晴天,家長(zhǎng)會(huì)。 家長(zhǎng)大會(huì)開好到教室時(shí),離放學(xué)已經(jīng)沒多少時(shí)間了。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,865評(píng)論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會(huì),身份的轉(zhuǎn)變要...
    余生動(dòng)聽閱讀 10,911評(píng)論 0 11

友情鏈接更多精彩內(nèi)容