netty线程模型和零拷贝机制
所属分类 netty
浏览量 1482
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日志