在網際網路的應用中有一個特點,高并發,但處理邏輯相對簡單。針對這個特别有時間我們可以相對的簡化下平時所有的WEB伺服器,來滿足這一的特點,而且更友善控制。Netty就是一個不錯的選擇,Netty 提供異步的、事件驅動的網絡應用程 另外與Spring一起使用,以快速開發高性能、高可靠性的網絡伺服器和用戶端程式。
最近的一個項目使用了這點,不錯的解決了這類的應用。下面是在了解這方面的時間找到的不錯的資料。
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工具管理項目開發)
<a href="http://blog.csdn.net/tanrenzong1986/article/details/6404256">http://blog.csdn.net/tanrenzong1986/article/details/6404256</a>
netty的性能非常高,能達到8000rps以上,見
<a href="http://blog.chinaunix.net/uid-11121450-id-3147009.html">http://blog.chinaunix.net/uid-11121450-id-3147009.html</a>
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隊列中的消息。
<a href="http://blog.csdn.net/north_eagle/article/details/6545357">http://blog.csdn.net/north_eagle/article/details/6545357</a>
本文轉自茄子_2008部落格園部落格,原文連結:http://www.cnblogs.com/xd502djj/archive/2012/06/25/2561318.html,如需轉載請自行聯系原作者。