Netty 初步

1.入門文檔 

如果是入門的話,官網的文檔已經相當好了。裏面的例子程序得仔細閱讀,這裏就不再重複轉載了。參見http://netty.io/wiki/user-guide.html 

2.爲什麼需要netty 
2.1 主要是scalibity和performance 

2.2 另外Netty In Action有一些說明,筆記如下: 

2.2.1 傳統的異步編程有2種模式:callback和Future 

2.2.2 3種API比較 
BIO: N個連接N個Thread 
NIO: N個連接1個Selector-->1個Thread 
NIO2:CompletionHandler避免了Selector的輪詢(JDK7) 

這張圖是BIO和NIO的比較。 
 

2.2.3 JDK的問題: 
1.跨平臺:linux上OK,windows上卻出問題 
2.ByteBuffer無法擴展 
3.scattering gathering可能有內存泄露(直到java6的後期update版本或者Java7才解決) 
4.epoll bug,可導致CPU 100%。  https://github.com/netty/netty/issues/327 
Netty解決了以上4點問題。 


3.Netty3,4,5 API不同點 

本文寫作時,各版本的最新版如下: 
netty3 3.9.0
netty4 4.0.18
netty5 5.0.0 Alpha1


3.1 ChannelHandler的變化 
首先有一些術語需要理解,請參見下面的表格和3張圖,從中可以看到netty3,4,5之間的很大的不同。 

收消息 上行,入站 InputStream.read(byte[])
發消息 下行,出站 OutputStream.write(byte[]), Socket.connect(SocketAddress), Socket.close()


Netty3使用了上行下行的概念 
 

Netty4使用了入站出站的概念 
 

Netty5則乾脆取消了兩者的劃分,統一爲一個概念 
 

Netty3: ChannelHandler有兩個子接口ChannelUpstreamHandler,ChannelDownstreamHandler, 
上行和下行,這裏的上行和下行和我們一般理解上的上下行不太一樣,爲何如此可以參考上面的3張圖。 
相應的類有SimpleChannelUpstreamHandler,SimpleChannelDownstreamHandler,以及一個同時實現兩個接口的SimpleChannelHandler 

 


Netty4: 接口變成了ChannelInboundHandler ChannelOutboundHandler,可能是爲了避免原來的上下行造成誤解,所以改成入站和出站了。 
相應的類有ChannelInboundHandlerAdapter,ChannelOutboundHandlerAdapter,我們只要選擇一個繼承就可以了。 

 


Netty5: 取消了進站、出站的劃分,統一爲繼承ChannelHandlerAdapter,原來的ChannelInboundHandlerAdapter,ChannelOutboundHandlerAdapter被廢棄。 

 

ChannelHandler的API,從中可以看到netty3,4,5之間的很大的不同。 


3.2 BootStrap的變化 

3.2.1 netty4構造ServerBootstrap時採用了構建者模式,使得代碼更優雅。 
Java代碼  收藏代碼
  1. EventLoopGroup bossGroup = new NioEventLoopGroup();  
  2. EventLoopGroup workerGroup = new NioEventLoopGroup();  
  3. ServerBootstrap b = new ServerBootstrap();  
  4. b.group(bossGroup, workerGroup)  
  5.  .channel(NioServerSocketChannel.class)  
  6.  .childHandler(new ChannelInitializer<SocketChannel>() {  
  7.     @Override  
  8.     public void initChannel(SocketChannel ch) throws Exception {  
  9.         ch.pipeline().addLast(new DiscardServerHandler());  
  10.     }  
  11. })  
  12.  .option(ChannelOption.SO_BACKLOG, 128)  
  13.  .childOption(ChannelOption.SO_KEEPALIVE, true);  

而netty3則是用最平常的setter。 
Java代碼  收藏代碼
  1. ChannelFactory factory = new NioServerSocketChannelFactory(  
  2.     Executors.newCachedThreadPool(),  
  3.     Executors.newCachedThreadPool());  
  4.   
  5. ServerBootstrap bootstrap = new ServerBootstrap(factory);  
  6.   
  7. bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  8.     public ChannelPipeline getPipeline() {  
  9.           return Channels.pipeline(new DiscardServerHandler());  
  10.     }  
  11. });  
  12.       
  13. bootstrap.setOption("child.tcpNoDelay"true);  
  14. bootstrap.setOption("child.keepAlive"true);  


3.2.2 對比一下netty3和4,我們發現netty4因爲採用了泛型的寫法(.channel(NioServerSocketChannel.class)),所以NioServerSocketChannelFactory就不需要透露給用戶了,這個工廠也被取消了。 

3.2.3 另外netty4引入了ChannelOption的常量定義,注意這個類是泛型的(ChannelOption<T>),用了這個技巧從而可以確保賦值安全,使得SO_BACKLOG只能傳一個int進來,SO_KEEPALIVE只能傳一個boolean進來。 
Java代碼  收藏代碼
  1. public static final ChannelOption<Integer> SO_BACKLOG  
  2. public static final ChannelOption<Boolean> SO_KEEPALIVE  


Bootstrap的API,netty4相比netty3有比較大的變化,而netty5和netty4比則基本相同。 

作爲初步,暫時先分析到這裏。其餘不同點有待以後繼續分析。
發佈了6 篇原創文章 · 獲贊 39 · 訪問量 72萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章