1 基本介绍

Bootstrap

Netty应用程序通过设置 bootstrap(引导)类开始,该类提供了一个用于应用程序网络层配置的容器。Bootstrap有两种类型,一种是用于客户端的Bootstrap,一种是用于服务端的ServerBootstrap。不管应用程序使用哪种协议,无论是客户端还是服务器都需要使用引导。Bootstrap用来连接远程主机,有1个EventLoopGroup。ServerBootstrap用来绑定本地端口,有2个EventLoopGroup。一个ServerBootstrap可以认为有2个Channel集合,第一个集合包含一个单例 ServerChannel,代表持有一个绑定了本地端口的socket;第二集合包含所有创建的Channel,处理服务器所接收到的客户端进来的连接。

Channel

Netty中的Channel可以理解为与socket具有相同功能的组件,它定义了与socket丰富的操作集:bind, clone, config, connect, isActive, isOpen, isWritable, read, write等。Netty提供了大量专门的Channel,包括AbstractChanel, AbstactNioByteChannel, AbstractNioChannel, EmbeddedChannel, LocalServerChannel, NioSocketChannel等。

ChannelHandler

ChannelHandler用于数据处理,可由特定事件触发。它可适用于几乎所有的动作,包括将一个对象转换为字节。

ChannelHandler是应用程序的核心,ChannelPipeline是ChannelHandler链的容器。

Netty中有两个方向的数据流,入站(ChannelInboundHandler)和出站(ChannelOutboundHandler),它们之间有一个明显的区别:若数据是从用户应用程序到远程主机则是“出站(outbound)”,相反若数据时从远程主机到用户应用程序则是“入站(inbound)”。数据在ChannelPipeline中的ChannelHandler链中流动。

一个事件可以通过使用ChanneHandlerContext被转发到下一个处理器中的当前链传递到每个方法。当ChannelHandler被添加到的ChannelPipeline它得到一个 ChannelHandlerContext,它代表一个ChannelHandler和ChannelPipeline之间的“绑定”。

最常见的处理器是接收到解码后的消息并应用一些业务逻辑到这些数据。要创建这样一个ChannelHandler,你只需要扩展基类SimpleChannelInboundHandler,其中T是想要进行处理的类型。

ChannelPipeline

ChannelPipeline为ChannelHandler链提供了一个容器,并提供了沿着链入站和出站的事件流动的管理API。每个Channel都有自己的ChannelPipeline,当Channel创建时自动创建。ChannelHandler通过ChannelInitializer接口安装到ChannelPipeline中。ChannelInitializer子类通过ServerBootstrap进行注册,当它的方法initChannel被调用时,这个对象将安装自定义的ChannelHandler集合到pipeline中,当这个操作完成时,ChannelInitializer子类则从ChannelPipeline自动删除自身。

EventLoop

EventLoop用于处理Channel的I/O操作,一个单一的EventLoop通常会处理多个Channel事件。一个EventLoopGroup可包含多个EventLoop,并且提供了迭代遍历方法。

ChannelFuture

Netty所有的I/O操作都是异步的。因为一个操作可能无法立即返回,我们需要一种方法在以后确定它的结果。出于这个目的,Netty提供了ChannelFuture接口,ChannelFuture接口的addListener方法注册了一个ChannelFutureListener,当操作完成时,可以被通知(不管成功与否)。可以将ChannelFuture对象想象为一个未来操作结果的占位符。尽管不能确定何时执行,但肯定会执行。

2 ByteBuf

ByteBuf是一个很好的经过优化的数据容器,我们可以将字节数据有效的添加到ByteBuf中或从ByteBuf中获取数据。ByteBuf有2部分:一个用于读,一个用于写。我们可以按顺序的读取数据,也可以通过调整读取数据的索引或者直接将读取位置索引作为参数传递给get方法来重复读取数据。写入数据到ByteBuf后,writerIndex(写入索引)增加。开始读字节后,readerIndex(读取索引)增加。你可以读取字节,直到写入索引和读取索引处在相同的位置,ByteBuf变为不可读。当访问数据超过数组的最后位,则会抛出 IndexOutOfBoundsException。调用ByteBuf的"read"或"write"开头的任何方法都会提升 相应的索引。另一方面,"set"、"get"操作字节将不会移动索引位置;他们只会操作相关的通过参数传入方法的相对索引。可以给ByteBuf指定一个最大容量值,这个值限制着ByteBuf的容量。任何尝试将写入索引超过这个值的行为都将导致抛出异常。ByteBuf的默认最大容量限制是Integer.MAX_VALUE。

Heap Buffer

最常用的模式是ByteBuf将数据存储在JVM的堆空间,这是通过将数据存储在数组的实现。堆缓冲区可以快速分配,当不使用时也可以快速释放。它还提供了直接访问数组的方法,通过ByteBuf.array()来获取 byte[]数据。

Direct Buffer

通过免去中间交换的内存拷贝,提升IO处理速度;直接缓冲区的内容可以驻留在垃圾回收扫描的堆区以外。

DirectBuffer在-XX:MaxDirectMemorySize=xxM大小限制下,使用Heap之外的内存,GC对此”无能为力”,也就意味着规避了在高负载下频繁的GC过程对应用线程的中断影响。

Composite Buffer

最后一种模式是复合缓冲区,我们可以创建多个不同的ByteBuf,然后提供一个这些ByteBuf组合的视图。复合缓冲区就像一个列表,我们可以动态的添加和删除其中的ByteBuf。

ByteBuf分配

ByteBufAllocator

为了减少分配和释放内存的开销,Netty 通过支持池类 ByteBufAllocator,可用于分配的任何 ByteBuf 我们已经描述过的类型的实例。

Channel channel = ...;
ByteBufAllocator allocator = channel.alloc(); //1
....
ChannelHandlerContext ctx = ...;
ByteBufAllocator allocator2 = ctx.alloc(); //2
...

Unpooled (非池化)缓存

当未引用ByteBufAllocator时,上面的方法无法访问到ByteBuf。对于这种情况,Netty提供一个称为Unpooled的工具类,它提供了静态辅助方法来创建非池化的ByteBuf实例。

ByteBufUtil

ByteBufUtil静态辅助方法来操作ByteBuf,因为这个API是通用的,与使用池无关,这些方法已经在外面的分配类实现。

也许最有价值的是hexDump()方法,这个方法返回指定ByteBuf中可读字节的十六进制字符串,可以用于调试程序时打印ByteBuf的内容。一个典型的用途是记录一个ByteBuf的内容进行调试。

Netty笔记的更多相关文章

  1. Netty笔记--ByteBuf释放

    参考资料:http://www.maljob.com/pages/newsDetail.html?id=394 参考资料:http://www.blogjava.net/liuguly/archive ...

  2. Netty笔记——技术点汇总

    目录 · Linux网络IO模型 · 文件描述符 · 阻塞IO模型 · 非阻塞IO模型 · IO复用模型 · 信号驱动IO模型 · 异步IO模型 · BIO编程 · 伪异步IO编程 · NIO编程 · ...

  3. Netty 笔记

    1.Netty 是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端. 2.早期Java API 使用的阻塞函数 // 创建一个新的ServerSocket, ...

  4. 我的Netty笔记

    pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w ...

  5. netty笔记(一)--Demo

    Netty是一个Java开源框架,用于传输数据.由server和client组成,封装了Java nio,支持TCP, UDP等协议.这里写了一Demo EchoClientHandler.java ...

  6. netty笔记-:Channel与ChannelHandlerContext执行write方法的区别

      在netty中有我们一般有两种发送数据的方式,即使用ChannelHandlerContext或者Channel的write方法,这两种方法都能发送数据,那么其有什么区别呢.这儿引用netty文档 ...

  7. netty笔记-:EpollEventLoopGroup:Caused by: java.lang.ExceptionInInitializerError:Caused by: java.lang.IllegalStateException: Only supported on Linux

    今天在翻看netty的源码的时候发现netty对EventLoopGroup的实现有不止常用的NIOEventLoopGroup ,一共有以下几种. EpollEventLoopGroup NioEv ...

  8. Netty学习笔记(一)

    学习圣思园Netty笔记,个人理解 2.netty宏观理解-本节内容: 1.阶段性事件驱动,一个请求分为若干阶段处理,每个阶段根据情况合理分配线程去处理,各阶段间通信采用异步事件驱动方式. 2.net ...

  9. Netty入门4之----如何实现长连接

    ​ 前面三章介绍了Netty的一些基本用法,这一章介绍怎么使用Netty来实现一个简单的长连接demo. 关于长连接的背景知识,可以参考<如何使用Socket实现长连接> ​ 一个简单的长 ...

随机推荐

  1. Spring MVC定义拦截器

    拦截器: package sy.Interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http ...

  2. bzoj1601: [Usaco2008 Oct]灌水

    经典延伸最小生成树问题... #include<cstdio> #include<cstring> #include<cctype> #include<alg ...

  3. Drupal 7.31版本爆严重SQL注入漏洞

    今早有国外安全研究人员在Twitter上曝出了Drupal 7.31版本的最新SQL注入漏洞,并给出了利用测试的EXP代码. 在本地搭建Drupal7.31的环境,经过测试,发现该利用代码可成功执行并 ...

  4. js中json与数组字符串的相互转化

    <SCRIPT LANGUAGE="JavaScript"> var t="{'firstName': 'cyra', 'lastName': 'richar ...

  5. Ajax+PHP简单入门教程

    Ajax 由 HTML.JavaScript™ 技术.DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序.对于Ajax,最核心的一个对象是XMLH ...

  6. mac下SSH很快被断开

    解决方法: 1. 切换到root账号:sudo bash -c 'su - root' 2. 修改/etc/ssh_config文件 ServerAliveCountMax 5 ServerAlive ...

  7. mvc项目,导出到Excel,中文显示乱码

      1 public class HomeController : Controller 2 { 3 static List<User> GetUsers() 4 { 5 List< ...

  8. C# Code for Downloading Stock Symbols z

    http://www.jarloo.com/download-stock-symbols/ If your using C# you can easily get the XML data using ...

  9. linux命令——scp 两台linux机器间文件或目录传输

    不同的Linux之间copy文件常用有3种方法: 第一种:ftp,也就是其中一台Linux安装ftpServer,这样可以另外一台使用ftp的client程序来进行文件的copy. 第二种:采用sam ...

  10. webdriver(python)学习笔记六——操作测试对象

    定位到具体对象后,就需要对其进行操作,比如点击.输入内容等. 一般来说,webdriver中比较常用的操作对象的方法有下面几个 click 点击对象 send_keys 在对象上模拟按键输入 clea ...