首页   快速返回

netty线程模型和零拷贝机制     所属分类 netty
BIO  Blocking IO 
Listen Accept read write 

NIO  non-blocking IO

Reactor利用事件驱动机制 ,注册事件 ,事件发生时调用相应的回调函数

read  decode  compute encode  send 


Reactor线程模型

Reactor单线程模型
acceptor和handler处理使用一个线程

Reactor多线程模型
accept线程 + handler处理线程池 
Acceptor线程用于监听客户端请求


Reactor主从模型
mainReactor + subReactor
mainReactor负责监听并Accept连接,然后将建立的socket 分派给subReactor
subReactor负责读写网络数据 业务处理 交给worker线程池 

int bossThreads = 2;
int workerThreads = 8;
EventLoopGroup bossGroup = new NioEventLoopGroup(bossThreads);
EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads);
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 1024);
b.group(bossGroup, workerGroup)
            
            
Netty  Accept连接和读写操作可以使用 单一线程 同一线程池 或 不同的线程池处理 

JDK NIO bug
JDK Epoll空轮询 导致  CPU 100%

            
TCP 粘包/拆包  
内置编解码器

LineBasedFrameDecoder
DelimiterBasedFrameDecoder
FixedLengthFrameDecoder
LengthFieldBasedFrameDecoder
 
服务端 客户端 使用固定长度的解码器 
ch.pipeline().addLast(new FixedLengthFrameDecoder(31))

零拷贝

读取文件 发送数据  
传统处理方式

1 File.read(bytes)
2 Socket.send(bytes)

需要四次数据拷贝和四次上下文切换

1. 数据从磁盘读取到内核缓冲区
2. 数据从内核缓冲区拷贝到用户缓冲区
3. 数据从用户缓冲区拷贝到内核的socket buffer
4. 数据从内核的socket buffer拷贝到网卡接口(硬件)的缓冲区

零拷贝实现
第二步和第三步可省略 
使用 FileChannel.transferTo  

1. 调用transferTo,数据从文件由DMA引擎拷贝到内核read buffer
2. 接着DMA从内核read buffer将数据拷贝到网卡接口buffer

使用 DMA 这两次拷贝不需要 cpu 参数

Netty中的零拷贝

bytebuffer  io.netty.buffer.ByteBuf
堆外内存 DirectMemory
DirectMemory 可以直接通过DMA发送到网卡接口

Composite Buffers
多个buffer组合 ,避免拷贝

FileChannel.transferTo

上一篇     下一篇
netty参数及相关代码

netty4 echo例子 日志记录

性能压测工具

netty组件

netty运行原理

netty4日志