Netty瞭解與小試

在互聯網的應用中有一個特點,高併發,但處理邏輯相對簡單。針對這個特別有時間我們可以相對的簡化下平時所有的WEB服務器,來滿足這一的特點,而且更方便控制。Netty就是一個不錯的選擇,Netty 提供異步的、事件驅動的網絡應用程 另外與Spring一起使用,以快速開發高性能、高可靠性的網絡服務器和客戶端程序。

最近的一個項目使用了這點,不錯的解決了這類的應用。下面是在瞭解這方面的時間找到的不錯的資料。

 

http://wenku.baidu.com/view/7765bc2db4daa58da0114a4c.html  深入淺出Netty

netty是JBOSS針對網絡開發的一套應用框架,它也是在NIO的基礎上發展起來的。netty基於異步的事件驅動,具有高性能、高擴展性等特性,它提供了統一的底層協議接口,使得開發者從底層的網絡協議(比如 TCP/IP、UDP)中解脫出來。就使用來說,開發者只要參考 Netty提供的若干例子和它的指南文檔,就可以放手開發基於Netty的服務端程序了。

   netty有幾個比較重要的概念,在此,僅做介紹,詳細可以參考netty文檔或源碼。

   1). channelBuffer:  Netty 的一個基本數據結構,這個數據結構存儲了一個字節序列。 類似於 NIO  ByteBuffer,但操作起來比ByteBuffer更爲簡單方便。

   2). ChannelFactory 是一個創建和管理 Channel 通道及其相關資源的工廠接口,它處理所有的 I/O 請求併產生相應的 I/O ChannelEvent 通道事件。

  3).ChannelHandler是所有I/O ChannelEvent事件的響應類,所有消息,包括netty通信異常事件,均在該響應類內處理。

  4).*** Bootstrap 是一個設置服務的幫助類。你甚至可以在這個服務中直接設置一個 Channel 通道。

  現在以實現一個UDP協議下的服務器應用程序爲例,演示netty通過spring註解開發服務器端。(在此以maven工具管理項目開發)

 

http://blog.csdn.net/tanrenzong1986/article/details/6404256

 

netty的性能非常高,能達到8000rps以上,見

 

http://blog.chinaunix.net/uid-11121450-id-3147009.html

 

 

Netty一般都通過bootStrap來啓動, 網絡動作過程就是服務器端bind->accept->read->write,客戶端 connect->read->write,一般bind或者connect後會有多次read、write。依據這種特性netty將bind,accept與read,write的線程分離,connect與read、write線程分離

 

 

 

一、Netty主要可以分爲3部分: buffer, channel, handle。

 

1、      Channelbuffer

 

l  所有的實現類中都提供,readerIndex, writerIndex兩個指針,無需nio buffer的flip.

 

l  可以通過ChannelBufferFactory來創建channelbuffer. 分爲兩類buffer

 

 HeapChannelBufferFactory: 在jvm堆上創建緩衝區,默認是BIG_ENDIAN排序

 

DirectChannelBufferFactory:對應nio ByteBuffer.allocateDirect(),直接緩衝區分配

 

l  WrappedChannelBuffer實現對ChannelBuffer封裝,通過其可以自定義channelbuffer.

 

 

 

2、      Channel:

 

通常每種類型的channel一般都有一個對應channelfactory類,以及一個channelconifg類。  通過channelfactory創建channel實例,然後由channelconifg來配置channel屬性。

 

l  ChannelGroup:  一組通道的集合,線程安全, 關閉的通道會自動從集合中刪除, 可以通過ChannelGroup廣播消息。

 

l  Channel的種類:

 

LocalChannel、 LocalServerChannel:本地通道、虛擬一個網絡。

 

DatagramChanneel: udp連接通道.

 

ServerSocketChannel、SoketChannel:  處理tcp/ip連接的通道。

 

l  Channelevent:  用於將:channel的相關信息 如channel本身,傳遞的數據,channel的狀態, future等等一起打包,在調用org.jboss.netty.channel.Channels類的各個靜態的fire方式中產生,然後在channelpipe中的sendUpsteam或sendDownStream中傳遞。

 

l  ChannelSink:處理pipeline中downstream結束後的事件。

 

 

 

3、      handler:

 

所有需要調用的handler都被包裝成ChannelHandlerContext,註冊到channelpipeline的一個map中,  通過兩個指針:head和tail保證map中的handle的調用順序。處理upstream時,通過head指針從前往後依次調用實現ChannelUpstreamHandler接口的handle.   downstream處理通過tail指針,從後往前依次調用實現ChannelDownstreamHandler接口的handle。  在downsream的channelpipeline傳送完後,ChannelSink的eventSunk方法完成對系統底層的調用處理。(ChannelSink和channel是通過attach的方式綁定到channelpipeline上)

 

Netty中已經提供的handler的種類如下:

 

l  codec handle。包括  64位機器的編碼、解碼,   字符集轉化,壓縮,http請求編碼、解碼; 序列化對象的編碼、解碼等等。通過codec handle我們可以直接往channel中寫java 對象。

 

l  Timeout handler通過jboss.netty.util.Timer來對讀寫超時或者閒置鏈接的通知,在handle中創建一個time對象,這個time對象包含一個定時器線程Work進程,在handle第一次被觸發時,啓動一個Work線程:監控超時事件。

 

l  Stream handler  用於異步處理大數據傳遞。通過將java.io.file對象包裝成ChunkedFile對象,進行傳遞,ChunkedFile的底層實現是RandomAccessFile.

 

l  Queue handler: 用戶將接受到的數據或需要發送的數據先存儲到一個queue隊列中,然後一次性的讀和寫。  包括BlockingReadHandler和BufferedWriteHandler. 注意在BlockingReadHandler將receivemessage存儲入queue後,其後的handler將不再處理 messageReceived,exceptionCaught 和channelClosed事件,因此BlockingReadHandler必須放在channelpipeline的最後。  同理BufferedWriteHandler。

 

 

 

4、      其他

 

l  org.jboss.netty.container 各種容器的兼容 Microcontainer OSGi Spring framework 整合接口

 

l  Bootstrap 啓動類: BootStrap: TCP服務器端啓動; ClientBootStrap:Tcp client端啓動和ConnectionlessBootstrap  UDP啓動。

 

 

 

二、服務器的啓動和客服端connect的過程

 

 

 

1 、服務器啓動

 

 bootstrap.bind(…)-> 觸發ServerSocketChannel.open()的事件(sendupstream)->捕捉open事件,channel.bind-> Channels.bind(…)  發起bind命令(sendDownstream)-> PipelineSink進行處理-> 使用socket進行bind,啓動boss進程。

 

 Boostrap.bind 方法包含兩個參數NioServerSocketChannelFactory、ChannelPipelineFactory。NioServerSocketChannelFactory包含連個線程池bossExecutor和workerExecutor,workerExecutor: 包含缺省爲處理器個數×2個NioWorker進程。

 

 2、服務器處理連接

 

 Boss啓動後,在監聽accept事件, 將捕獲到的事件作爲一個task放到一個niowork進程

 

的registerTaskQueue隊列中。

 

3、服務器端接收並處理數據

 

  NioWorker.run()->nioworker. processSelectedKeys()->Nioworker. Read()將從SocketChannel讀取的數據封裝成ChannelBuffer ->調用fireMessageReceived(channel,buffer)產生upstream事件 –> 由註冊到Pipeline中的Hanlder進行處理

 

4、客戶端connection

 

同服務器啓動一樣也需要創建一個NioClientSocketChannelFactory和一個ChannelPipelineFactory。  同服務器端不同的是client端的boss進程不要監聽,它將本地發出的建立的鏈接的請求封裝成task放入一個registerTaskQueue,boss負責消費Queue隊列中的消息。

http://blog.csdn.net/north_eagle/article/details/6545357

發佈了27 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章