尊重原創,轉載注明出處,原文地址:http://www.cnblogs.com/cishengchongyan/p/6121065.html
博主最近在做網絡相關的項目,因此有契機學習netty,先是看各種的netty資料后來自己看源碼,希望在此把自己的學習歷程分享出來。因為我最初對netty的了解也僅限於知道它是一個優秀的網絡框架,可以說是一無所知,想來想去就把這個文章系列起名《解開迷霧看netty》,也是我學習netty的真實寫照。該系列的博文全部是基於Netty4。
初學者看優秀的開源代碼時不知道是不是都有一個通病,就是非常迷茫,我最初在看netty時就是這種感覺,不知道從哪里下手,經常東看一點西看一點,往往形成不了連貫的思路。當我們按照一條主線看代碼時也會有這樣的問題,經常會因為主線兩側的內容把我們的思路帶跑偏。因此,我對看源碼的淺見是:一、不能亂看,沿一條主線看;二、過程中一定要及時的回歸主線,否則很難形成連貫的思路。
在第一篇文章中我們首先先了解一下netty是什么以及netty中的成員,可以說是一道開胃菜,也是后面學習的基礎。
套用Netty官網的一句話:Netty是一個異步的、事件驅動的網絡應用框架,可以快速開發高性能的網絡協議。下圖是來自netty home的官方圖:
從上圖中可以看出,netty包含了三塊:傳輸服務(方便我們快速開發出網絡協議)、協議支持(支持了哪些現有的協議)和核心網絡模型(底層核心實現)。
對於上圖我們不做過多的描述,由於是學習和研究netty,所以我們的關注點也在Core上。眾所周知,Netty底層是Nio以及Reactor模式,如果是小白可以先在我的另一篇博客NIO及Reactor模式中了解一下概念。
下面進入主題,我們先大概了解一下Netty和NIO中都有哪些重要的成員:
1.Channel(NIO):字面理解為“通道”,用於完成一個I/O請求,也可以理解為通信的載體。
2.Selector(NIO):選擇器,也可被稱為多路復用器,是實現非阻塞IO的關鍵。它類似於一個監聽器,通過地調用select()或selectNow()可以得到目前有多少channel處於I/O就緒狀態,通過調用selectedKeys()得到就緒狀態的SelectionKey的集合,然后遍歷這一集合便可得到所有就緒狀態的SelectableChannel,進一步便可以做相應的操作。
3.Buffer(NIO):緩沖區,在NIO中數據的讀寫都是面向buffer的,可以理解為內存里開辟的一塊臨時保存數據的區域,而本質上就是一個數組,然后基於position、limit、capacity、address來操作這個數組。在netty中衍生出ChannelBuffer。
4.ChannelHandler(Netty):ChannelHandler負責與I/O無關的業務邏輯處理。可以處理或攔截ChannelInboundInvoker或ChannelOutboundInvoker操作,分別用於處理上行和下行的消息,並將其轉發到ChannelPipeline中交給下一個ChannelHandler。
5.ChannelEvent(Netty):Netty是基於事件驅動的,ChannelEvent是事件(數據或者狀態改變)載體,例如傳輸的數據對應MessageEvent,狀態的改變對應ChannelStateEvent。當對Channel進行操作時,會產生一個ChannelEvent,並發送到ChannelPipeline。ChannelPipeline會選擇一個ChannelHandler進行處理。這個ChannelHandler處理之后,可能會產生新的ChannelEvent,並流轉到下一個ChannelHandler。
6.ChannelPipeline(Netty):Pipeline的中文含義是“管道”,傳輸途徑。也就是說在ChannelPipeline控制ChannelEvent事件分發和傳遞,流轉到ChannelHandler中進行處理。ChannelPipeline包含兩條線路:Upstream和Downstream,分別對應上行和下行的通信。
7.ChannelFuture(Netty):在Netty中所有的I/O操作都是異步的,因此我們總是得不到最終實際的I/O結果,而是得到ChannelFuture,它會包含一些I/O執行狀態的結果。ChannelFuture往往配合監聽器使用,在其中注冊一個監聽器,當操作執行成功或失敗時監聽會自動觸發,相當於一個回調。
8.EventLoop(Netty):Netty中的線程池模型,后面會詳細介紹,下一篇將會先從boss線程和worker線程說起。