Netty解析

原创 2015年11月17日 22:17:39

Netty 

Netty是什么?

 

本质:JBoss做的一个Jar包

 

目的:快速开发高性能、高可靠性的网络服务器和客户端程序

 

优点:提供异步的、事件驱动的网络应用程序框架和工具

 

通俗的说:一个好使的处理Socket的东东

 

 

如果没有Netty?

 

远古:java.net + java.io

 

近代:java.nio

 

其他:Mina,Grizzly

 

为什么不是Mina?

 

1、都是Trustin Lee的作品,Netty更晚;

2、Mina将内核和一些特性的联系过于紧密,使得用户在不需要这些特性的时候无法脱离,相比下性能会有所下降,Netty解决了这个设计问题;

3、Netty的文档更清晰,很多Mina的特性在Netty里都有;

4、Netty更新周期更短,新版本的发布比较快;

5、它们的架构差别不大,Mina靠apache生存,而Netty靠jboss,和jboss的结合度非常高,Netty有对google protocal buf的支持,有更完整的ioc容器支持(spring,guice,jbossmc和osgi);

6、Netty比Mina使用起来更简单,Netty里你可以自定义的处理upstream events 或/和 downstream events,可以使用decoder和encoder来解码和编码发送内容;

7、Netty和Mina在处理UDP时有一些不同,Netty将UDP无连接的特性暴露出来;而Mina对UDP进行了高级层次的抽象,可以把UDP当成"面向连接"的协议,而要Netty做到这一点比较困难。

 

 

Netty的特性

 

设计

统一的API,适用于不同的协议(阻塞和非阻塞)

基于灵活、可扩展的事件驱动模型

高度可定制的线程模型

可靠的无连接数据Socket支持(UDP)

 

性能

更好的吞吐量,低延迟

更省资源

尽量减少不必要的内存拷贝

 

安全

完整的SSL/TLS和STARTTLS的支持

能在Applet与Android的限制环境运行良好

 

健壮性

不再因过快、过慢或超负载连接导致OutOfMemoryError

不再有在高速网络环境下NIO读写频率不一致的问题

 

易用

完善的JavaDoc,用户指南和样例

简洁简单

仅信赖于JDK1.5

 

看例子吧!

 

Server端:

 

Java代码  收藏代码
  1. package me.hello.netty;  
  2.   
  3. import org.jboss.netty.bootstrap.ServerBootstrap;  
  4. import org.jboss.netty.channel.*;  
  5. import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;  
  6. import org.jboss.netty.handler.codec.string.StringDecoder;  
  7. import org.jboss.netty.handler.codec.string.StringEncoder;  
  8.   
  9. import java.net.InetSocketAddress;  
  10. import java.util.concurrent.Executors;  
  11.   
  12. /** 
  13.  * God Bless You! 
  14.  * Author: Fangniude 
  15.  * Date: 2013-07-15 
  16.  */  
  17. public class NettyServer {  
  18.     public static void main(String[] args) {  
  19.         ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));  
  20.   
  21.         // Set up the default event pipeline.  
  22.         bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  23.             @Override  
  24.             public ChannelPipeline getPipeline() throws Exception {  
  25.                 return Channels.pipeline(new StringDecoder(), new StringEncoder(), new ServerHandler());  
  26.             }  
  27.         });  
  28.   
  29.         // Bind and start to accept incoming connections.  
  30.         Channel bind = bootstrap.bind(new InetSocketAddress(8000));  
  31.         System.out.println("Server已经启动,监听端口: " + bind.getLocalAddress() + ", 等待客户端注册。。。");  
  32.     }  
  33.   
  34.     private static class ServerHandler extends SimpleChannelHandler {  
  35.         @Override  
  36.         public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {  
  37.             if (e.getMessage() instanceof String) {  
  38.                 String message = (String) e.getMessage();  
  39.                 System.out.println("Client发来:" + message);  
  40.   
  41.                 e.getChannel().write("Server已收到刚发送的:" + message);  
  42.   
  43.                 System.out.println("\n等待客户端输入。。。");  
  44.             }  
  45.   
  46.             super.messageReceived(ctx, e);  
  47.         }  
  48.   
  49.         @Override  
  50.         public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {  
  51.             super.exceptionCaught(ctx, e);  
  52.         }  
  53.   
  54.         @Override  
  55.         public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {  
  56.             System.out.println("有一个客户端注册上来了。。。");  
  57.             System.out.println("Client:" + e.getChannel().getRemoteAddress());  
  58.             System.out.println("Server:" + e.getChannel().getLocalAddress());  
  59.             System.out.println("\n等待客户端输入。。。");  
  60.             super.channelConnected(ctx, e);  
  61.         }  
  62.     }  
  63. }  

 

客户端:

 

Java代码  收藏代码
  1. package me.hello.netty;  
  2.   
  3. import org.jboss.netty.bootstrap.ClientBootstrap;  
  4. import org.jboss.netty.channel.*;  
  5. import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;  
  6. import org.jboss.netty.handler.codec.string.StringDecoder;  
  7. import org.jboss.netty.handler.codec.string.StringEncoder;  
  8.   
  9. import java.io.BufferedReader;  
  10. import java.io.InputStreamReader;  
  11. import java.net.InetSocketAddress;  
  12. import java.util.concurrent.Executors;  
  13.   
  14. /** 
  15.  * God Bless You! 
  16.  * Author: Fangniude 
  17.  * Date: 2013-07-15 
  18.  */  
  19. public class NettyClient {  
  20.   
  21.     public static void main(String[] args) {  
  22.         // Configure the client.  
  23.         ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));  
  24.   
  25.         // Set up the default event pipeline.  
  26.         bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  27.             @Override  
  28.             public ChannelPipeline getPipeline() throws Exception {  
  29.                 return Channels.pipeline(new StringDecoder(), new StringEncoder(), new ClientHandler());  
  30.             }  
  31.         });  
  32.   
  33.         // Start the connection attempt.  
  34.         ChannelFuture future = bootstrap.connect(new InetSocketAddress("localhost"8000));  
  35.   
  36.         // Wait until the connection is closed or the connection attempt fails.  
  37.         future.getChannel().getCloseFuture().awaitUninterruptibly();  
  38.   
  39.         // Shut down thread pools to exit.  
  40.         bootstrap.releaseExternalResources();  
  41.     }  
  42.   
  43.     private static class ClientHandler extends SimpleChannelHandler {  
  44.         private BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));  
  45.   
  46.         @Override  
  47.         public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {  
  48.             if (e.getMessage() instanceof String) {  
  49.                 String message = (String) e.getMessage();  
  50.                 System.out.println(message);  
  51.   
  52.                 e.getChannel().write(sin.readLine());  
  53.   
  54.                 System.out.println("\n等待客户端输入。。。");  
  55.             }  
  56.   
  57.             super.messageReceived(ctx, e);  
  58.         }  
  59.   
  60.         @Override  
  61.         public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {  
  62.             System.out.println("已经与Server建立连接。。。。");  
  63.             System.out.println("\n请输入要发送的信息:");  
  64.             super.channelConnected(ctx, e);  
  65.   
  66.             e.getChannel().write(sin.readLine());  
  67.         }  
  68.     }  
  69. }  

 

Netty整体架构



 

Netty组件

 

ChannelFactory

Boss

Worker

Channel

ChannelEvent

Pipeline

ChannelContext

Handler

Sink

 

Server端核心类

NioServerSocketChannelFactory

NioServerBossPool 

NioWorkerPool

NioServerBoss

NioWorker

NioServerSocketChannel

NioAcceptedSocketChannel

DefaultChannelPipeline

NioServerSocketPipelineSink

Channels

 

 

ChannelFactory

Channel工厂,很重要的类

保存启动的相关参数

 

NioServerSocketChannelFactory

NioClientSocketChannelFactory

NioDatagramChannelFactory

 

这是Nio的,还有Oio和Local的

 

 

SelectorPool

 

Selector的线程池

 

NioServerBossPool 默认线程数:1

NioClientBossPool      1

NioWorkerPool      2 * Processor

NioDatagramWorkerPool

 

 

Selector

 

选择器,很核心的组件

 

NioServerBoss

NioClientBoss

NioWorker

NioDatagramWorker

 

 

Channel

 

通道

 

NioServerSocketChannel

NioClientSocketChannel

NioAcceptedSocketChannel

NioDatagramChannel

 

Sink

负责和底层的交互

如bind,Write,Close等

 

NioServerSocketPipelineSink

NioClientSocketPipelineSink

NioDatagramPipelineSink

 

Pipeline

负责维护所有的Handler

 

ChannelContext

一个Channel一个,是Handler和Pipeline的中间件

 

Handler

对Channel事件的处理器

 

 

ChannelPipeline

 



 

 

 

优秀的设计----事件驱动



 

 

优秀的设计----线程模型



 

注意事项

 

解码时的Position

 

Channel的关闭

 

更多Handler

 

 

Channel的关闭

 

用完的Channel,可以直接关闭;

1、ChannelFuture加Listener

2、writeComplete

 

一段时间没用,也可以关闭

TimeoutHandler

Netty4详解三:Netty架构设计

读完这一章,我们基本上可以了解到Netty所有重要的组件,对Netty有一个全面的认识,这对下一步深入学习Netty是十分重要的,而学完这一章,我们其实已经可以用Netty解决一些常规的问题了。 ...
  • suifeng3051
  • suifeng3051
  • 2014年06月06日 10:52
  • 25730

Netty入门三:Netty概要讲解,全面了解Netty,做到胸有成竹

http://www.tuicool.com/articles/mEJvYb    读完这一章,我们基本上可以了解到Netty所有重要的组件,对Netty有一个全面的认识,这对下一步...
  • xiaxiaorui2003
  • xiaxiaorui2003
  • 2016年06月13日 15:27
  • 1756

Netty4详解一:理解Netty的设计理念NIO

初步了解Netty            Netty是一个NIO的编程框架,Netty是非常容易和快速开发出网络应用程序的,它提供了一种全新的形式来方便你编写网络应用:它提供了对一些对复杂问题的抽象,...
  • suifeng3051
  • suifeng3051
  • 2014年04月10日 13:35
  • 10177

一篇文章,读懂Netty的高性能架构之道

Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用...
  • marvel_java
  • marvel_java
  • 2016年11月13日 20:53
  • 2126

netty原理详解

NIO客户端序列图 声明:本文是《Netty 权威指南》的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文。 步骤一:打开SocketChannel,绑定客户端本地地址(可选,...
  • wanbf123
  • wanbf123
  • 2017年09月22日 10:07
  • 715

Netty详细讲解

github代码地址:https://github.com/gudepeng/gdpNetty 本教程使用的Netty版本为4.1.15.Final 一、Netty详解 Netty是由JBOSS提供的...
  • u014459326
  • u014459326
  • 2017年10月23日 10:45
  • 170

Netty——基本使用介绍

1.为什么选择Netty 上一篇文章我们已经了解了Socket通信(IO/NIO/AIO)编程,对于通信模型已经有了一个基本的认识。其实上一篇文章中,我们学习的仅仅是一个模型,如果想把这些真正的用于实...
  • haoyuyang
  • haoyuyang
  • 2016年11月20日 19:51
  • 27733

Netty详解

原文链接 http://www.blogjava.net/czihong/articles/391927.html Netty提供异步的、事件驱动的网络应...
  • yanlinwang
  • yanlinwang
  • 2014年01月16日 10:41
  • 5789

Guice 依赖注入

简介 Java企业应用开发社区在连接对象方面花了很大功夫。你的Web应用如何访问中间层服 务?你的服务如何连接到登录用户和事务管理器?关于这个问题你会发现很多通用的和特 定的解决方案。有一些方案依赖...
  • zengqiang1
  • zengqiang1
  • 2016年11月22日 10:22
  • 696

netty初析

Netty是什么? 本质:JBoss做的一个Jar包 目的:快速开发高性能、高可靠性的网络服务器和客户端程序 优点:提供异步的、事件驱动的网络应用程序框架和工具通俗的说:一个好使的处理Socke...
  • luo_yifan
  • luo_yifan
  • 2016年06月30日 11:09
  • 516
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Netty解析
举报原因:
原因补充:

(最多只允许输入30个字)