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