Netty組件理解(轉載)

來源:互聯網
上載者:User

標籤:發送   代碼   pipeline   位元組流   線程   用兩個   架構   情況   第一個   

轉載的文章,寫的非常好。 

一、先縱覽一下Netty,看看Netty都有哪些組件?

 

     為了更好的理解和進一步深入Netty,我們先總體認識一下Netty用到的組件及它們在整個Netty架構中是怎麼協調工作的。Netty應用中必不可少的組件:
  • Bootstrap or ServerBootstrap
  • EventLoop
  • EventLoopGroup
  • ChannelPipeline
  • Channel
  • Future or ChannelFuture
  • ChannelInitializer
  • ChannelHandler
     Bootstrap,一個Netty應用通常由一個Bootstrap開始,它主要作用是配置整個Netty程式,串聯起各個組件。     Handler,為了支援各種協議和處理資料的方式,便誕生了Handler組件。Handler主要用來處理各種事件,這裡的事件很廣泛,比如可以是串連、資料接收、異常、資料轉換等。     ChannelInboundHandler,一個最常用的Handler。這個Handler的作用就是處理接收到資料時的事件,也就是說,我們的商務邏輯一般就是寫在這個Handler裡面的,ChannelInboundHandler就是用來處理我們的核心商務邏輯。     ChannelInitializer,當一個連結建立時,我們需要知道怎麼來接收或者發送資料,當然,我們有各種各樣的Handler實現來處理它,那麼ChannelInitializer便是用來配置這些Handler,它會提供一個ChannelPipeline,並把Handler加入到ChannelPipeline。     ChannelPipeline,一個Netty應用基於ChannelPipeline機制,這種機制需要依賴於EventLoop和EventLoopGroup,因為它們三個都和事件或者事件處理相關。     EventLoops的目的是為Channel處理IO操作,一個EventLoop可以為多個Channel服務。     EventLoopGroup會包含多個EventLoop。     Channel代表了一個Socket連結,或者其它和IO操作相關的組件,它和EventLoop一起用來參與IO處理。     Future,在Netty中所有的IO操作都是非同步,因此,你不能立刻得知訊息是否被正確處理,但是我們可以過一會等它執行完成或者直接註冊一個監聽,具體的實現就是通過Future和ChannelFutures,他們可以註冊一個監聽,當操作執行成功或失敗時監聽會自動觸發。總之,所有的操作都會返回一個ChannelFuture。  二、Netty是如何處理串連請求和商務邏輯的呢?-- Channels、Events 和 IO       Netty是一個非阻塞的、事件驅動的、網路編程架構。當然,我們很容易理解Netty會用線程來處理IO事件,對於熟悉多線程編程的人來說,你或許會想到如何同步你的代碼,但是Netty不需要我們考慮這些,具體是這樣:      一個Channel會對應一個EventLoop,而一個EventLoop會對應著一個線程,也就是說,僅有一個線程在負責一個Channel的IO操作。     關於這些名詞之間的關係,可以見:                :當一個串連到達,Netty會註冊一個channel,然後EventLoopGroup會分配一個EventLoop綁定到這個channel,在這個channel的整個生命週期過程中,都會由綁定的這個EventLoop來為它服務,而這個EventLoop就是一個線程。     說到這裡,那麼EventLoops和EventLoopGroups關係是如何的呢?我們前面說過一個EventLoopGroup包含多個Eventloop,但是我們看一下下面這幅圖,這幅圖是一個繼承樹,從這幅圖中我們可以看出,EventLoop其實繼承自EventloopGroup,也就是說,在某些情況下,我們可以把一個EventLoopGroup當做一個EventLoop來用。  三、我們來看看如何配置一個Netty應用?-- BootsStrapping       我們利用BootsStrapping來配置netty 應用,它有兩種類型,一種用於Client端:BootsStrap,另一種用於Server端:ServerBootstrap,要想區別如何使用它們,你僅需要記住一個用在Client端,一個用在Server端。下面我們來詳細介紹一下這兩種類型的區別:     1.第一個最明顯的區別是,ServerBootstrap用於Server端,通過調用bind()方法來綁定到一個連接埠監聽串連;Bootstrap用於Client端,需要調用connect()方法來串連伺服器端,但我們也可以通過調用bind()方法返回的ChannelFuture中擷取Channel去connect伺服器端。     2.用戶端的Bootstrap一般用一個EventLoopGroup,而伺服器端的ServerBootstrap會用到兩個(這兩個也可以是同一個執行個體)。為何伺服器端要用到兩個EventLoopGroup呢?這麼設計有明顯的好處,如果一個ServerBootstrap有兩個EventLoopGroup,那麼就可以把第一個EventLoopGroup用來專門負責綁定到連接埠監聽串連事件,而把第二個EventLoopGroup用來處理每個接收到的串連,下面我們用一幅圖來展現一下這種模式:            PS: 如果僅由一個EventLoopGroup處理所有請求和串連的話,在並發量很大的情況下,這個EventLoopGroup有可能會忙於處理已經接收到的串連而不能及時處理新的串連請求,用兩個的話,會有專門的線程來處理串連請求,不會導致請求逾時的情況,大大提高了並發處理能力。      我們知道一個Channel需要由一個EventLoop來綁定,而且兩者一旦綁定就不會再改變。一般情況下一個EventLoopGroup中的EventLoop數量會少於Channel數量,那麼就很有可能出現一個多個Channel公用一個EventLoop的情況,這就意味著如果一個Channel中的EventLoop很忙的話,會影響到這個Eventloop對其它Channel的處理,這也就是為什麼我們不能阻塞EventLoop的原因。     當然,我們的Server也可以只用一個EventLoopGroup,由一個執行個體來處理串連請求和IO事件,請看下面這幅圖:         四、我們看看Netty是如何處理資料的?-- Netty核心ChannelHandler       下面我們來看一下netty中是怎樣處理資料的,回想一下我們前面講到的Handler,對了,就是它。說到Handler我們就不得不提ChannelPipeline,ChannelPipeline負責安排Handler的順序及其執行,下面我們就來詳細介紹一下他們:  ChannelPipeline and handlers     我們的應用程式中用到的最多的應該就是ChannelHandler,我們可以這麼想象,資料在一個ChannelPipeline中流動,而ChannelHandler便是其中的一個個的小閥門,這些資料都會經過每一個ChannelHandler並且被它處理。這裡有一個公用介面ChannelHandler:            從中我們可以看到,ChannelHandler有兩個子類ChannelInboundHandler和ChannelOutboundHandler,這兩個類對應了兩個資料流向,如果資料是從外部流入我們的應用程式,我們就看做是inbound,相反便是outbound。其實ChannelHandler和Servlet有些類似,一個ChannelHandler處理完接收到的資料會傳給下一個Handler,或者什麼不處理,直接傳遞給下一個。下面我們看一下ChannelPipeline是如何安排ChannelHandler的:            從中我們可以看到,一個ChannelPipeline可以把兩種Handler(ChannelInboundHandler和ChannelOutboundHandler)混合在一起,當一個資料流進入ChannelPipeline時,它會從ChannelPipeline頭部開始傳給第一個ChannelInboundHandler,當第一個處理完後再傳給下一個,一直傳遞到管道的尾部。與之相對應的是,當資料被寫出時,它會從管道的尾部開始,先經過管道尾部的“最後”一個ChannelOutboundHandler,當它處理完成後會傳遞給前一個ChannelOutboundHandler。資料在各個Handler之間傳遞,這需要調用方法中傳遞的ChanneHandlerContext來操作, 在netty的API中提供了兩個基類分ChannelOutboundHandlerAdapter和ChannelOutboundHandlerAdapter,他們僅僅實現了調用ChanneHandlerContext來把訊息傳遞給下一個Handler,因為我們只關心處理資料,因此我們的程式中可以繼承這兩個基類來協助我們做這些,而我們僅需實現處理資料的部分即可。     我們知道InboundHandler和OutboundHandler在ChannelPipeline中是混合在一起的,那麼它們如何區分彼此呢?其實很容易,因為它們各自實現的是不同的介面,對於inbound event,Netty會自動跳過OutboundHandler,相反若是outbound event,ChannelInboundHandler會被忽略掉。     當一個ChannelHandler被加入到ChannelPipeline中時,它便會獲得一個ChannelHandlerContext的引用,而ChannelHandlerContext可以用來讀寫Netty中的資料流。因此,現在可以有兩種方式來發送資料,一種是把資料直接寫入Channel,一種是把資料寫入ChannelHandlerContext,它們的區別是寫入Channel的話,資料流會從Channel的頭開始傳遞,而如果寫入ChannelHandlerContext的話,資料流會流入管道中的下一個Handler。    五、我們最關心的部分,如何處理我們的商務邏輯? -- Encoders, Decoders and Domain Logic       Netty中會有很多Handler,具體是哪種Handler還要看它們繼承的是InboundAdapter還是OutboundAdapter。當然,Netty中還提供了一些列的Adapter來協助我們簡化開發,我們知道在Channelpipeline中每一個Handler都負責把Event傳遞給下一個Handler,如果有了這些輔助Adapter,這些額外的工作都可自動完成,我們只需覆蓋實現我們真正關心的部分即可。此外,還有一些Adapter會提供一些額外的功能,比如編碼和解碼。那麼下面我們就來看一下其中的三種常用的ChannelHandler: Encoders和Decoders     因為我們在網路傳輸時只能傳輸位元組流,因此,才發送資料之前,我們必須把我們的message型轉換為bytes,與之對應,我們在接收資料後,必須把接收到的bytes再轉換成message。我們把bytes to message這個過程稱作Decode(解碼成我們可以理解的),把message to bytes這個過程成為Encode。     Netty中提供了很多現成的編碼/解碼器,我們一般從他們的名字中便可知道他們的用途,如ByteToMessageDecoder、MessageToByteEncoder,如專門用來處理Google Protobuf協議的ProtobufEncoder、 ProtobufDecoder。     我們前面說過,具體是哪種Handler就要看它們繼承的是InboundAdapter還是OutboundAdapter,對於Decoders,很容易便可以知道它是繼承自ChannelInboundHandlerAdapter或 ChannelInboundHandler,因為解碼的意思是把ChannelPipeline傳入的bytes解碼成我們可以理解的message(即Java Object),而ChannelInboundHandler正是處理Inbound Event,而Inbound Event中傳入的正是位元組流。Decoder會覆蓋其中的“ChannelRead()”方法,在這個方法中來調用具體的decode方法解碼傳遞過來的位元組流,然後通過調用ChannelHandlerContext.fireChannelRead(decodedMessage)方法把編碼好的Message傳遞給下一個Handler。與之類似,Encoder就不必多少了。 Domain Logic     其實我們最最關心的事情就是如何處理接收到的解碼後的資料,我們真正的商務邏輯便是處理接收到的資料。Netty提供了一個最常用的基類SimpleChannelInboundHandler<T>,其中T就是這個Handler處理的資料的類型(上一個Handler已經替我們解碼好了),訊息到達這個Handler時,Netty會自動調用這個Handler中的channelRead0(ChannelHandlerContext,T)方法,T是傳遞過來的資料對象,在這個方法中我們便可以任意寫我們的商務邏輯了。

Netty組件理解(轉載)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.