Netty笔记
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笔记的更多相关文章
- Netty笔记--ByteBuf释放
参考资料:http://www.maljob.com/pages/newsDetail.html?id=394 参考资料:http://www.blogjava.net/liuguly/archive ...
- Netty笔记——技术点汇总
目录 · Linux网络IO模型 · 文件描述符 · 阻塞IO模型 · 非阻塞IO模型 · IO复用模型 · 信号驱动IO模型 · 异步IO模型 · BIO编程 · 伪异步IO编程 · NIO编程 · ...
- Netty 笔记
1.Netty 是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端. 2.早期Java API 使用的阻塞函数 // 创建一个新的ServerSocket, ...
- 我的Netty笔记
pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w ...
- netty笔记(一)--Demo
Netty是一个Java开源框架,用于传输数据.由server和client组成,封装了Java nio,支持TCP, UDP等协议.这里写了一Demo EchoClientHandler.java ...
- netty笔记-:Channel与ChannelHandlerContext执行write方法的区别
在netty中有我们一般有两种发送数据的方式,即使用ChannelHandlerContext或者Channel的write方法,这两种方法都能发送数据,那么其有什么区别呢.这儿引用netty文档 ...
- netty笔记-:EpollEventLoopGroup:Caused by: java.lang.ExceptionInInitializerError:Caused by: java.lang.IllegalStateException: Only supported on Linux
今天在翻看netty的源码的时候发现netty对EventLoopGroup的实现有不止常用的NIOEventLoopGroup ,一共有以下几种. EpollEventLoopGroup NioEv ...
- Netty学习笔记(一)
学习圣思园Netty笔记,个人理解 2.netty宏观理解-本节内容: 1.阶段性事件驱动,一个请求分为若干阶段处理,每个阶段根据情况合理分配线程去处理,各阶段间通信采用异步事件驱动方式. 2.net ...
- Netty入门4之----如何实现长连接
前面三章介绍了Netty的一些基本用法,这一章介绍怎么使用Netty来实现一个简单的长连接demo. 关于长连接的背景知识,可以参考<如何使用Socket实现长连接> 一个简单的长 ...
随机推荐
- UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi ...
- Android之 环境搭建
一. 使用ADT Bundle多合一下载包 下载地址:链接:http://pan.baidu.com/s/1gepNRjX 密码: ozdi 说 明:多合一下载包,里面包含了:sdk + ...
- ionic安装拍照选照片插件
1.安装插件,也可以用ionic plugin add .... phonegap local plugin add https://git-wip-us.apache.org/repos/asf/c ...
- macro names must be identifiers
1.错把 #include 写成了 #define 会报这个错 2.定义一个不存在的宏业会报这个错,如加了-DANDRO 而ANDRO不存在
- I.MX6 开机 闪红屏
/************************************************************************** * I.MX6 开机 闪红屏 * 说明: * 本 ...
- POJ 1523 SPF (割点,连通分量)
题意:给出一个网络(不一定连通),求所有的割点,以及割点可以切分出多少个连通分量. 思路:很多种情况. (1)如果给的图已经不是连通图,直接“ No SPF nodes”. (2)求所有割点应该不难 ...
- HDU 4267 A Simple Problem with Integers
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- POJ 1573 Robot Motion
Robot Motion Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12978 Accepted: 6290 Des ...
- <转>如何测试一个杯子
在软件测试的面试中, 经常会碰到类似的问题. 比如:如何测试一个杯子, 或者如何测试一只笔. 要求你设计20个以上的test case. 这类的面试题目,是考察面试者是否熟悉各种软件测试方法, 设计t ...
- oracle修改密码及账户锁定
在oracle修改密码的时候,一种是用dba账户来修改用户的密码,一种是用户自己修改自己的密码: SQL> alter user kel identified by kel; 解锁命令: SQL ...