【攻破技术盲点】— 网络IO模型的分析(上)

简介: 【攻破技术盲点】— 网络IO模型的分析(上)

Linux的网络IO模型


网络IO的本质是socket的读写,socket在Linux中被抽象为流IO可以理解为对流的操作。



IO的分类和范畴


IO本身可以分为内存IO、网络IO和磁盘IO还有缓存IO等,一般讨论IO时更多是指后(网络IO和磁盘IO,因为这两个是最慢的哈哈),此处特别分析和说明网络IO




操作处理的分类


阻塞/非阻塞


针对函数/方法的实现方式而言,即数据就绪之前是立刻返回还是等待,即发起IO请求后是否会阻塞


阻塞IO机制


阻塞IO情况下,当用户调用read后,用户线程会被阻塞,等内核数据准备好并且数据从内核缓冲区拷贝到用户态缓存区后read才会返回。可以看到是阻塞的两个部分


  • CPU把数据从磁盘读到内核缓冲区。


  • CPU把数据从内核缓冲区拷贝到用户缓冲区。


image.png

非阻塞IO机制

image.png

  • 非阻塞IO发出read请求后发现数据没准备好,会继续往下执行,此时应用程序会不断轮询polling内核询问数据是否准备好,当数据没有准备好时,内核立即返回EWOULDBLOCK错误。


  • 直到数据被拷贝到应用程序缓冲区,read请求才获取到结果。并且你要注意!这里最后一次 read 调用获取数据的过程,是一个同步的过程,是需要等待的过程。这里的同步指的是内核态的数据拷贝到用户程序的缓存区这个过程。



同步/异步


IO读操作指数据流经:网络 -> 内核缓冲区 -> 用户内存


  • 同步和异步的主要区别在于数据从内核缓冲区 -> 用户内存这个过程需不需要用户进程等待


  • 等待内核态准备数据结束之后,会自动回通知用户态的线程进行读取信息数据,此时之前用户态的线程不需要等待,可以去做其他操作。


对于一个网络IO,会涉及到两个系统对象,一个是调用这个IO的process(or thread)【用户态】,另一个就是系统内核(kernel)【内核态】



当一个用户态发生read操作发生时,它会经历两个阶段:


  • 第一阶段:用户态线程等待内核态的数据准备 (Waiting for the data to be ready)


  • 第二阶段:用户态线程,将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)。


  • 第一步:通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区


  • 第二步:把数据从内核缓冲区复制到(用户态)应用进程缓冲区。网络应用处理的是两大类问题:网络IO、数据计算。前者给应用带来的性能瓶颈更大。



网络IO的模型大致有如下几种:


  • 同步模型(synchronous IO)


  • 阻塞IO模型(blocking IO)


  • 非阻塞IO模型(non-blocking IO)


  • 多路复用IO模型(multiplexing IO)


  • 信号驱动IO模型(signal-driven IO)


  • 异步IO(asynchronous IO)




阻塞IO模型(blocking IO)


Linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程如下:


image.png

当用户进程调用了recvfrom这个系统调用,如上所述,会有两个阶段


准备数据:


  • 很多时候数据在一开始还没有到达,这个时候kernel就要等待足够的数据到来。而用户进程会一直阻塞。


  • 当kernel等到数据准备好了,它会将数据从kernel中拷贝到用户内存,然后kernel返回,用户进程结束block状态,重新运行。


Blocking IO的特点就是IO执行的两个阶段都是block了的。





非阻塞IO模型(non-blocking IO)[poll]


在Linux中,可以通过设置socket使其变为non-blocking,其流程如下:

image.png

  • 当用户进程调用了recvfrom这个系统调用,如果kernel中的数据还没有准备好,那么用户进程不会block而是立刻返回一个error,即从用户的角度而言,不需要等待,马上得到一个结果。


  • 从图中可以看出,用户进程在判断结果是一个error后,了解到数据还没有准备好,于是就不断重复上述操作直至kernel中的数据准备好,然后它马上将数据拷贝到了用户内存,然后返回。





多路复用IO模型(multiplexing IO)


select/epoll/evpoll,也被称作是Event-Driven IO。好处是单个process可以同时处理多个网络连接的IO。


  • 基本原理可见下面的“IO复用技术”。也叫多路IO就绪通知。


  • 这是一种进程预先告知内核的能力,让内核发现进程指定的一个或多个IO条件就绪了,就通知用户进程


  • 使得一个进程能在一连串的事件上等待。

image.png

  • 这个流程和Blocking IO的流程其实并没有太多不同,事实上仅从图中看起来,由于需要进行两次系统调用,可能更差一些。但是,Select的优势在于它可以同时处理多个连接。


  • 如果处理的连接数不是很高的话,使用“Select/Epoll 的 Web Server”不一定比使用“多线程 + BIO的Web Server”性能更好,反而延迟会更大。



Select/Epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。


在IO多路复用模型中,实际中,对于每一个socket,一般都设置成为non-blocking,但是,如上图所示,整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。




异步IO(asynchronous IO)


用户进程发起read操作之后,立刻就可以开始去做其它的事。


image.png


  1. 从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block


  1. kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了



比较


image.png


非阻塞和异步的区别


经过上面的介绍,会发现non-blocking IO和asynchronous IO的区别还是很明显的。


  • 在non-blocking IO中,虽然进程大部分时间都不会被block,但是它仍然要求进程去主动的check,并且当数据准备完成以后,也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存。


  • asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据。




IO复用技术


在IO编程过程中,当需要处理多个请求时,可以使用多线程和IO复的方式进行处理。



IO复用是什么?


把多个IO的阻塞复用到一个select之类的阻塞上,从而使得系统在单线程的情况下同时支持处理多个请求


IO复用常见的应用场景:


  • 服务器需要同时处理多个处于监听状态和多个连接状态的套接字;


  • 服务器需要处理多种网络协议的套接字


  • IO复用的实现方式目前主要有select、poll和epoll/evpoll。


select和poll的原理基本相同:


  1. 注册待侦听的fd(这里的fd创建时最好使用非阻塞)


  1. 每次调用都去检查这些fd的状态,当有一个或者多个fd就绪的时候返回


  1. 返回结果中包括已就绪和未就绪的fd



select和poll与epoll机制的比较


Linux网络编程过程中,相比于select/poll,epoll是有着更明显优势的一种选择


  • 支持一个进程打开的socket描述符不受限制(仅受限于操作系统的最大文件句柄数 unlimit)。


  • Select的缺陷:一个进程所打开的FD受限,默认是2048;尽管数值可以更改,但同样可能导致网络效率下降;可以选择多进程的解决方案,但是进程的创建本身代价不小,而且进程间数据同步远比不上线程间同步的高效。


  • epoll所支持的FD上限是最大可以打开文件的数目:/proc/sys/fs/file-max


IO效率可能随着文件描述符数目的增加而线性下降。


  • epoll扫描系统的机制不同


  • select/poll是线性扫描FD的集合


  • epoll是根据FD上面的回调函数实现的,活跃的socket会主动去调用该回调函数,其它socket则不会,相当于市是一个AIO,只不过推动力在OS内核。


  • 使用mmap加速内核与用户空间的消息传递,zero-copy的一种


  • epoll的API更加简单


  • IO复用还有一个 水平触发 和 边缘触发 的概念:


  • 水平触发:当就绪的fd未被用户进程处理后,下一次查询依旧会返回,这是select和poll的触发方式。


  • 边缘触发:无论就绪的fd是否被处理,下一次不再返回。理论上性能更高,但是实现相当复杂,并且任何意外的丢失事件都会造成请求处理错误。epoll默认使用水平触发,通过相应选项可以使用边缘触发。





IO模型的总结


最后,再举几个不是很恰当的例子来说明这四个IO Model,有A,B,C,D四个人在钓鱼:


  • A用的是最老式的鱼竿,所以呢,得一直守着,等到鱼上钩了再拉杆;(同步阻塞)


  • B的鱼竿有个功能,能够显示是否有鱼上钩,所以呢,B就和旁边的MM聊天,隔会再看看有没有鱼上钩,有的话就迅速拉杆;(非阻塞)


  • C用的鱼竿和B差不多,但他想了一个好办法,就是同时放好几根鱼竿,然后守在旁边,一旦有显示说鱼上钩了,它就将对应的鱼竿拉起来;(io多路复用机制)


  • D是个有钱人,干脆雇了一个人帮他钓鱼,一旦那个人把鱼钓上来了,就给D发个短信。(异步机制)












相关文章
|
1月前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
68 11
|
7天前
|
边缘计算 容灾 网络性能优化
算力流动的基石:边缘网络产品技术升级与实践探索
本文介绍了边缘网络产品技术的升级与实践探索,由阿里云专家分享。内容涵盖三大方面:1) 云编一体的混合组网方案,通过边缘节点实现广泛覆盖和高效连接;2) 基于边缘基础设施特点构建一网多态的边缘网络平台,提供多种业务形态的统一技术支持;3) 以软硬一体的边缘网关技术实现多类型业务网络平面统一,确保不同网络间的互联互通。边缘网络已实现全球覆盖、差异化连接及云边互联,支持即开即用和云网一体,满足各行业需求。
|
25天前
|
负载均衡 网络协议 网络性能优化
动态IP代理技术详解及网络性能优化
动态IP代理技术通过灵活更换IP地址,广泛应用于数据采集、网络安全测试等领域。本文详细解析其工作原理,涵盖HTTP、SOCKS代理及代理池的实现方法,并提供代码示例。同时探讨配置动态代理IP后如何通过智能调度、负载均衡、优化协议选择等方式提升网络性能,确保高效稳定的网络访问。
163 2
|
2天前
|
存储 人工智能 安全
AI时代的网络安全:传统技术的落寞与新机遇
在AI时代,网络安全正经历深刻变革。传统技术如多因素身份认证、防火墙和基于密码的系统逐渐失效,难以应对新型攻击。然而,AI带来了新机遇:智能化威胁检测、优化安全流程、生物特征加密及漏洞管理等。AI赋能的安全解决方案大幅提升防护能力,但也面临数据隐私和技能短缺等挑战。企业需制定清晰AI政策,强化人机协作,推动行业持续发展。
33 16
|
1月前
|
机器学习/深度学习 安全 网络安全
网络安全词云图与技术浅谈
### 网络安全词云图与技术浅谈 本文介绍了通过词云图展示网络安全关键术语的方法,并探讨了构建现代网络安全体系的关键要素。词云图利用字体大小和颜色突出高频词汇,如恶意软件、防火墙、入侵检测系统等。文中提供了生成词云图的Python代码示例,包括安装依赖库和调整参数。此外,文章详细讨论了恶意软件防护、加密技术、身份验证、DDoS防御、社会工程学防范及威胁情报等核心技术,强调了多层次、多维度的安全策略的重要性。
68 11
网络安全词云图与技术浅谈
|
1月前
|
存储 安全 物联网
浅析Kismet:无线网络监测与分析工具
Kismet是一款开源的无线网络监测和入侵检测系统(IDS),支持Wi-Fi、Bluetooth、ZigBee等协议,具备被动监听、实时数据分析、地理定位等功能。广泛应用于安全审计、网络优化和频谱管理。本文介绍其安装配置、基本操作及高级应用技巧,帮助用户掌握这一强大的无线网络安全工具。
70 9
浅析Kismet:无线网络监测与分析工具
|
1月前
|
数据采集 机器学习/深度学习 人工智能
基于AI的网络流量分析:构建智能化运维体系
基于AI的网络流量分析:构建智能化运维体系
124 13
|
1月前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
117 3
|
1月前
|
监控 安全 BI
什么是零信任模型?如何实施以保证网络安全?
随着数字化转型,网络边界不断变化,组织需采用新的安全方法。零信任基于“永不信任,永远验证”原则,强调无论内外部,任何用户、设备或网络都不可信任。该模型包括微分段、多因素身份验证、单点登录、最小特权原则、持续监控和审核用户活动、监控设备等核心准则,以实现强大的网络安全态势。
141 2
|
1月前
|
存储 安全 网络安全
云计算与网络安全:技术融合的双刃剑
在数字化浪潮中,云计算如同一股不可阻挡的力量,推动着企业和个人用户步入一个高效、便捷的新时代。然而,随之而来的网络安全问题也如影随形,成为制约云计算发展的阿喀琉斯之踵。本文将探讨云计算服务中的网络安全挑战,揭示信息保护的重要性,并提供实用的安全策略,旨在为读者呈现一场技术与安全的较量,同时指出如何在享受云服务带来的便利的同时,确保数据的安全和隐私。
36 6

热门文章

最新文章