知识卡片

五种网络I/O模型的类比与Zuul从阻塞到异步的性能跃迁

结构图卡

内容

一次网络请求要经过”数据从远程主机到达内核缓冲区”和”数据从内核缓冲区 复制到应用程序地址空间”两个阶段,网络I/O模型的差异就在于这两阶段各自 怎么处理,可归为两类五种。同步/异步区分的是”调用方要不要等结果”,阻塞/ 非阻塞区分的是”等待期间线程是否被挂起”。用”怎么拿到盒饭”类比:异步I/O 如同点外卖,付款后自己该干嘛干嘛,饭做好后骑手主动送上门(数据复制 完成后由操作系统通知,一定是非阻塞的);阻塞I/O如同去食堂等着,饭没好 就干等着(线程休眠,逻辑清晰但上下文切换成本高);非阻塞I/O是每隔几 分钟去看一眼好了没(避免休眠但频繁轮询浪费CPU,实际不太常用);多路 复用I/O是代表全宿舍去食堂,同时等好几份饭,谁的先好就先送谁的(本质 仍是阻塞,但一条线程能同时处理多个连接,是当前高并发网络应用的主流, 细分为select/epoll/kqueue等实现);信号驱动I/O是跟厨师说好了叫你,你人 先走,但被叫到后还要自己去食堂端回来(复制阶段仍需自己完成、仍阻塞, 这是它与真异步I/O的核心区别:异步I/O收到的通知是”复制已经做完了”,信号 驱动收到的通知只是”可以开始复制了”)。这套理论直接映射到七层网关的性能 差异上:Zuul 1.0用最经典的”一线程对一连接”阻塞I/O模型,后端服务是I/O 密集型时会因频繁上下文切换拖累性能;Zuul 2.0改用基于Netty的异步I/O, 大幅减少线程数,实测比1.0快约20%。

结构图

flowchart TD
    A[网络I/O两阶段: 等待数据到缓冲区 + 复制到应用地址空间] --> B{同步 调用方等待结果}
    A --> C[异步: 复制完成后系统主动通知<br/>如叫外卖]
    B --> D[阻塞I/O: 等待期间线程休眠<br/>如食堂干等]
    B --> E[非阻塞I/O: 定期轮询查看<br/>如反复回食堂看]
    B --> F[多路复用I/O: 一线程同时等多个连接<br/>如代宿舍打饭]
    B --> G[信号驱动I/O: 通知后仍需自己去复制<br/>如厨师喊你但要自己端]

参考来源

- 位置:《凤凰架构:构建可靠的大型分布式系统》第7章"从类库到服务" 7.2.2节"网络I/O模型"(源文件:_epub-src对应OEBPS/Text/chapter90.xhtml) - 结论依据:原文用"领盒饭"类比逐一解释异步I/O、阻塞I/O、非阻塞I/O、 多路复用I/O、信号驱动I/O五种模型的差异,并说明Zuul 1.0用阻塞I/O、 2.0改用基于Netty的异步I/O、性能提升约20%,直接支撑本卡片的结构梳理。 - 原始内容:异步I/O……数据到达缓冲区后,不需要由调用进程主动进行从 缓冲区复制数据的操作,而是复制完成后由操作系统向线程发送信号……信号 驱动I/O与异步I/O的区别是"从缓冲区获取数据"这个步骤的处理……Zuul 2.0 大约要比Zuul 1.0快上20%左右。