作者:微信小助手
发布时间:2022-01-11T19:11:34
大家好,我是悟空呀。 今天我们从内核角度来聊下 Netty 的 IO 模型。这篇很长,建议收藏起来慢慢看~ 我们都知道Netty是一个高性能异步事件驱动的网络框架。它的设计异常优雅简洁,扩展性高,稳定性强。拥有非常详细完整的用户文档。 同时内置了很多非常有用的模块基本上做到了开箱即用,用户只需要编写短短几行代码,就可以快速构建出一个具有 本文我们来探讨下支持Netty具有 由Netty的高吞吐
,低延时
,更少的资源消耗
,高性能(非必要的内存拷贝最小化)
等特征的高并发网络应用程序。高吞吐
,低延时
特征的基石----netty的网络IO模型
。网络IO模型
开始,我们来正式揭开本系列Netty源码解析的序幕。网络包接收流程
网络数据帧
通过网络传输到达网卡时,网卡会将网络数据帧通过
DMA的方式
放到
环形缓冲区RingBuffer
中。
RingBuffer
是网卡在启动的时候分配和初始化
的环形缓冲队列
。当RingBuffer满
的时候,新来的数据包就会被丢弃
。我们可以通过ifconfig
命令查看网卡收发数据包的情况。其中overruns
数据项表示当RingBuffer满
时,被丢弃的数据包
。如果发现出现丢包情况,可以通过ethtool命令
来增大RingBuffer长度。
DMA操作完成
时,网卡会向CPU发起一个
硬中断
,告诉
CPU
有网络数据到达。CPU调用网卡驱动注册的
硬中断响应程序
。网卡硬中断响应程序会为网络数据帧创建内核数据结构
sk_buffer
,并将网络数据帧
拷贝
到
sk_buffer
中。然后发起
软中断请求
,通知
内核
有新的网络数据帧到达。
sk_buff
缓冲区,是一个维护网络帧结构的双向链表
,链表中的每一个元素都是一个网络帧
。虽然 TCP/IP 协议栈分了好几层,但上下不同层之间的传递,实际上只需要操作这个数据结构中的指针,而无需进行数据复制
。
ksoftirqd
发现有软中断请求到来,随后调用网卡驱动注册的
poll函数
,
poll函数
将
sk_buffer
中的
网络数据包
送到内核协议栈中注册的
ip_rcv函数