Netty初步 --概念

news/2024/7/7 20:55:00

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不同点

本文写作时,各版本的最新版如下:

netty33.9.0
netty44.0.18
netty55.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);  
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
 .channel(NioServerSocketChannel.class)
 .childHandler(new ChannelInitializer<SocketChannel>() {
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ch.pipeline().addLast(new DiscardServerHandler());
    }
})
 .option(ChannelOption.SO_BACKLOG, 128)
 .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);  
ChannelFactory factory = new NioServerSocketChannelFactory(
    Executors.newCachedThreadPool(),
    Executors.newCachedThreadPool());

ServerBootstrap bootstrap = new ServerBootstrap(factory);

bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
    public ChannelPipeline getPipeline() {
          return Channels.pipeline(new DiscardServerHandler());
    }
});
    
bootstrap.setOption("child.tcpNoDelay", true);
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  
public static final ChannelOption<Integer> SO_BACKLOG
public static final ChannelOption<Boolean> SO_KEEPALIVE



Bootstrap的API,netty4相比netty3有比较大的变化,而netty5和netty4比则基本相同。

作为初步,暂时先分析到这里。其余不同点有待以后继续分析。


http://www.niftyadmin.cn/n/3959850.html

相关文章

Ubuntu腾讯云主机安装分布式memcache服务器,C#中连接云主机进行存储的示例

Ubuntu腾讯云主机安装分布式memcache服务器&#xff0c;C#中连接云主机进行存储的示例&#xff08;github代码&#xff1a;https://github.com/qq719862911/MemcacheTestDemo&#xff09; 1、腾讯云安装memcache服务器&#xff0c;并且启动服务器。 1)安装Memcache服务端 sudo …

Practical Netty (3) 在Netty中使用Protobuf

Practical Netty (3) 在Netty中使用Protobuf 作者&#xff1a;柳大Poechant&#xff08;钟超&#xff09;邮箱&#xff1a;zhongchao.ustc#gmail.com&#xff08;# -> &#xff09;博客&#xff1a;Blog.CSDN.net/Poechant 微博&#xff1a;weibo.com/lauginhom 日期&#x…

Atom改国内源

linux #进入目录 cd /home/你的用户名/.atom#创建文件并编辑 vim .apmrc#添加国内源 registryhttps://registry.npm.taobao.org#保存退出#测试是否成功 apm install --check windows #进入目录 找到C:\Users\用户名\.atom目录#创建名为 .apmrc 的文件并编辑#添加国内源 registr…

几种JAVA加密算法

1. MD5加密&#xff0c;常用于加密用户名密码&#xff0c;当用户验证时。   protected byte[] encrypt(byte[] obj) ...{   try ...{   MessageDigest md5 MessageDigest.getInstance("MD5");   md5.update(obj);   return md5.digest();   } catch (No…

Asky极简教程:零基础1小时学编程(已更新前8节)

Asky极简架构 开源Asky极简架构、超轻量级、高并发、水平扩展、微服务架构 《Asky极简教程&#xff1a;零基础1小时学编程》开源教程 零基础入门&#xff0c;从零开始全程演示&#xff0c;如何开发一个大型互联网系统&#xff0c;开源教程 开源代码 开源解决方案零基础1小时学…

[算法]两数之和,三数之和

1. 两数之和 给定一个整数数组和一个目标值&#xff0c;找出数组中和为目标值的两个数。 你可以假设每个输入只对应一种答案&#xff0c;且同样的元素不能被重复利用。 示例: 给定 nums [2, 7, 11, 15], target 9因为 nums[0] nums[1] 2 7 9 所以返回 [0, 1] LeetCode&am…

Qt(Mac) 进程的启动

试了半天&#xff0c;终于成功了&#xff01;&#xff01;&#xff01;&#xff01;&#xff08;教程都是Windows的&#xff09; 1.与Windows不一样&#xff0c;Mac的要在了路径前加上open&#xff1b; 2.例 图为把一个按钮与TextEdit程序进程联系&#xff0c;点击后就可以启动…

Hibernate的三种连接池设置C3P0、Proxool和DBCP

Xml代码 <!-- JDBC驱动程序 --> <property name"connection.driver_class">com.mysql.jdbc.Driver</property> <property name"connection.url">jdbc:mysql://localhost:3306/struts?useUnicodetrue&characterEncodingGBK&l…