是什么
高性能NIO网络框架。
目的
方便用户基于netty快速开发应用程序。
架构
netty线程模型
分为3种:单线程模型,单网络线程多事件线程处理模型,多网络线程多事件线程处理模型。
单线程指的是一个线程即要处理IO的连接/读/写也要处理业务事件,对应一个boss EventLoopGroup。
单网络线程多事件线程处理模型指的是:网络处理线程一个(连接,网络读写),但会有一个线程池处理业务事件。
多网络线程多事件线程处理模型就是:一个boss EventLoopGroup,一个work EventLoopGroup。
netty解决epoll jdk selector cpu100%问题
问题原因:linux当只有一个连接的时候被客户端中断掉,此时会返回给selector,但就绪事件列表为空。jdk selector不能进行处理select key,重新到while true,然后不断的循环反复。
解:超过一次次数重建selector。
netty拆包及粘包处理
netty对于拆包,粘包处理基本有两种方法,一种是基于长度,一种是基于分割符。而基于长度的编解码,就是在header部分定义一个总消息长度或消息体长度,服务端接收到消息后再处理。
这里分析netty中的LineBasedFrameDecoder基于 \n 的分割符处理器。
这个处理器,基本处理过程如下:
1.客户端发送 abc 消息给服务端。
2.服务端首次接收到数据包会将其存入一个堆外内存buffer cumulation中,在发现当前buffer存在 \n 分割符时,直接返回该buffer给下个handler处理。
否则当没有发现 \n时返回null,即暂不处理。
3.客户端继续发送 d\n 给服务端
4.服务端接收到消息后,因为cumulation buffer不为空,所以将新接收到的buffer拷到 cumulation buffer中。
然后进行处理,发列有 \n,则将之前保存的abc及 d交给下一个handler处理。
注:这里的拷贝调用如下:
static void copyMemory(long srcAddr, long dstAddr, long length) {
//UNSAFE.copyMemory(srcAddr, dstAddr, length);
while (length > 0) {
long size = Math.min(length, UNSAFE_COPY_THRESHOLD);
UNSAFE.copyMemory(srcAddr, dstAddr, size);
length -= size;
srcAddr += size;
dstAddr += size;
}
}
这里直接将srcAddr所在地址的缓存,内容大小为length拷到dstAddr所在地址的缓存。
问题:
netty所说的零拷贝,在这里还是有发生堆外内存的拷贝
CompositeChannelBuffer netty 在何时会使用?