netty
2025-08-01 15:50:48 0 举报
AI智能生成
java 网络编程 易上手框架
作者其他创作
大纲/内容
nio
阻塞io
用户空间等待系统空间返回数据
异步io
多路复用
epoll
selector
aio
reactor
事件驱动
实现
bytebuf
堆外内存
无锁化
1. 跟handler绑定的 eventExecutor 是什么时候绑定上去的,是怎么绑定到handler上的;
1、注册的时候
2、创建ChannelHandlerContext对象,绑定handler和eventExecutor,然后添加进pipeline
2. eventExecutor 中的线程,是什么时候进行创建的,是怎么创建的;
1、新连接且线程没有的达到设置的值的时候,创建eventExecutor
默认ThreadPerTaskExecutor
2、
3. NioEventLoop线程执行 handler 中的方法,如果指定了 eventExecutor,是什么时候做的线程切换,是怎么切换的;
通过调用selector的wakeup
开始的时候创建了一个wakeupFD 文件件描述符
通过本地方法向wakeupSinkFD写入一个字节
4. eventExecutor 是怎么接过 NioEventLoop的任务来执行的,又是怎么执行的;
1、processSelectedKeysOptimized查找事件,并找到对应的Channel
2、channel对应的pipeline处理具体事件
3、如果是当前channel绑定的eventExecutor直接执行,如果不是,创建对应的task放入相应的eventExecutor中
4、NioEventLoop中的run方法的定时周期处理,NioEventLoop中调用runAllTasks方法执行任务,执行相应的task
零拷贝
概念
零,零次拷贝
拷贝,数据复制
零拷贝并不是没有拷贝数据
减少用户态/内核态的切换次数以及CPU拷贝的次数
用户态
进程运行于用户空间
内核态
进程运行于内核空间
CPU上下文
CPU上下文切换
先把前一个任务的CPU上下文(也就是CPU寄存器和程序计数器)保存起来
然后加载新任务的上下文到这些寄存器和程序计数器
最后再跳转到程序计数器所指的新位置,运行新任务
虚拟内存
虚拟内存空间可以远远大于物理内存空间
多个虚拟内存可以指向同一个物理地址
内核空间和用户空间的虚拟地址映射到同一个物理地址
DMI技术
用户应用进程调用read函数,向操作系统发起IO调用,进入阻塞状态,等待数据返回。
CPU收到指令后,对DMA控制器发起指令调度。
DMA收到IO请求后,将请求发送给磁盘;
磁盘将数据放入磁盘控制缓冲区,并通知DMA
DMA将数据从磁盘控制器缓冲区拷贝到内核缓冲区。
DMA向CPU发出数据读完的信号,把工作交换给CPU,由CPU负责将数据从内核缓冲区拷贝到用户缓冲区。
用户应用进程由内核态切换回用户态,解除阻塞状态
实现
mmap+wirte
用户进程通过mmap方法向操作系统内核发起IO调用,上下文从用户态切换为内核态。
CPU利用DMA控制器,把数据从硬盘中拷贝到内核缓冲区。
上下文从内核态切换回用户态,mmap方法返回。
用户进程通过write方法向操作系统内核发起IO调用,上下文从用户态切换为内核态。
CPU将内核缓冲区的数据拷贝到的socket缓冲区。
CPU利用DMA控制器,把数据从socket缓冲区拷贝到网卡,上下文从内核态切换回用户态,write调用返回。
sendfile
用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态
DMA控制器,把数据从硬盘中拷贝到内核缓冲区。
CPU将读缓冲区中数据拷贝到socket缓冲区
DMA控制器,异步把数据从socket缓冲区拷贝到网卡,
上下文(切换2)从内核态切换回用户态,sendfile调用返回。
带MDI采集的sendfile
用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态
DMA控制器,把数据从硬盘中拷贝到内核缓冲区。
CPU把内核缓冲区中的文件描述符信息(包括内核缓冲区的内存地址和偏移量)发送到socket缓冲区
DMA控制器根据文件描述符信息,直接把数据从内核缓冲区拷贝到网卡
上下文(切换2)从内核态切换回用户态,sendfile调用返回。
传统 IO 的执行流程
用户应用进程调用read函数,向操作系统发起IO调用,读取到内核缓冲区
CPU把内核缓冲区数据,拷贝到用户应用缓冲区
用户应用进程通过write函数,发起IO调用,socket缓冲区
DMA控制器把数据从socket缓冲区,拷贝到网卡设备
发生四次上下文切换
用户态到内核态
内核态到用户态
用户态到内核态
内核态到用户态
四次数据拷贝
DMI拷贝到内核缓冲
CPU拷贝到用户态
CPU拷贝到socket缓冲区
DMI拷贝到网卡设备
原因
使用 JDK 自带的 NIO 需要了解太多的概念,编程复杂。
Netty 底层 IO 模型随意切换,而这一切只需要做微小的改动。
Netty自带的拆包解包,异常检测等机制让我们从 NIO 的繁重细节中脱离出来,只需关心业务逻辑即可。
Netty解决了JDK 的很多包括空轮训在内的 Bug。
Netty底层对线程,Selector 做了很多细小的优化,精心设计的 Reactor 线程做到非常高效的并发处理。
自带各种协议栈,让我们处理任何一种通用协议都几乎不用亲自动手。
Netty社区活跃,遇到问题随时邮件列表或者 issue。
Netty已经历各大RPC框架(Dubbo),消息中间件(RocketMQ),大数据通信(Hadoop)框架的广泛的线上验证,健壮性无比强大。
Netty 底层 IO 模型随意切换,而这一切只需要做微小的改动。
Netty自带的拆包解包,异常检测等机制让我们从 NIO 的繁重细节中脱离出来,只需关心业务逻辑即可。
Netty解决了JDK 的很多包括空轮训在内的 Bug。
Netty底层对线程,Selector 做了很多细小的优化,精心设计的 Reactor 线程做到非常高效的并发处理。
自带各种协议栈,让我们处理任何一种通用协议都几乎不用亲自动手。
Netty社区活跃,遇到问题随时邮件列表或者 issue。
Netty已经历各大RPC框架(Dubbo),消息中间件(RocketMQ),大数据通信(Hadoop)框架的广泛的线上验证,健壮性无比强大。
0 条评论
下一页