您正在查看静态缓存页面 · 查看完整动态版本 · 登录 参与讨论

io_uring的觉醒:一场内核深处的性能革命

✨步子哥 (steper) 2026年01月18日 03:03 0 次浏览

你正站在一个拥挤的旧式火车站台。传统I/O就像老式的售票窗口:每次你要发车(读写数据),都得排队喊一嗓子(系统调用),售票员(内核)慢吞吞地核对、盖章、再喊回来告诉你车开了没有。队伍长、开销大、效率低得让人抓狂。而iouring的出现,就像突然建起了一条高速磁悬浮专线:你把所有车票(I/O请求)一次性塞进一个共享的“信箱”(提交队列),内核随时取走处理,完事后再把通知单扔进另一个“信箱”(完成队列)。你不用再来回跑腿,系统调用次数骤降,性能像坐了火箭一样起飞。

这不是科幻,而是Linux内核从5.1版本开始悄然掀起的一场异步I/O革命。今天,我们就来一起走进这个高效、优雅却常常被低估的接口,聊聊它到底是怎么诞生的、需要什么条件才能用、又有哪些隐藏的“彩蛋”和“坑”。

🚀 高速专线的起点:iouring的基本面貌

iouring的核心理念非常简单,却异常强大:用户空间和内核空间共享两个环形队列——提交队列(Submission Queue,简称SQ)和完成队列(Completion Queue,简称CQ)。你把I/O操作描述成一条条“提交条目”(Submission Queue Entry,SQE)扔进SQ,内核消费它们,处理完后再把结果写进CQ。你只需要偶尔轮询一下CQ,就能知道哪些活儿干完了。

为什么这能快?因为传统系统调用(read/write/aio)每次都要陷入内核、上下文切换、参数拷贝,代价高得离谱。iouring把这些开销批量化、共享化,几乎把系统调用次数降到了接近零。打个比方:传统I/O像每次点外卖都要打电话确认地址;iouring则像把一周的订单一次性发给骑手,骑手自己安排路线,送完批量通知你。

小贴士:如果你还不熟悉异步I/O,可以把它想象成餐厅里的“自助点餐机”。你先把所有菜品选好放进购物车(SQ),厨房(内核)按顺序做,做好了放进取餐区(CQ),你随时去拿就行,不用站在柜台前干等。

🛠️ 想上车,先看票:基本的系统要求

iouring可不是随便哪个Linux都能玩的。它从Linux 5.1正式亮相,所以你的内核版本必须≥5.1。怎么查?在终端敲一句uname -r,如果看到5.1或更高,恭喜,你已经站在了起跑线。

但光有版本还不够。内核编译时必须打开CONFIG_IO_URING=y这个配置选项。主流发行版里,Ubuntu 20.04+、Fedora、Debian 11+、Rocky Linux 9、RHEL 9 基本都默认开启了,但如果你用的是极简自定义内核,或者某些嵌入式发行版,那就要自己去/boot/config-$(uname -r)里grep一下确认。

架构方面,x8664和arm64是完全没问题的,其他如riscv64、powerpc也在逐步跟进,但可能需要额外补丁。简单说,只要是现代服务器或桌面Linux,大概率都能直接用。

🔍 层层解锁的宝箱:高级特性与内核版本的对应关系

iouring就像一款持续更新的游戏,基础玩法5.1就有了,但真正爽快的“神器”是一个个随着内核版本解锁的。

  • 5.1:游戏正式开服。基本的读、写、poll、fsync等操作全部就位,你已经能感受到性能飞跃。
  • 5.4:优化了环的内存映射,只需一次mmap就能把SQ和CQ都映射进用户空间,减少了系统调用和页面错误。
  • 5.14+:网络I/O真正起飞。支持多路复用的socket操作,在高并发服务器场景下表现亮眼(想想Nginx或Redis那种百万连接的场景)。
  • 5.19:多shot accept横空出世。一次提交就能接受多个连接,不用每次accept都重新提交SQE,极大降低高并发下的CPU占用。
  • 6.0:多shot receive加入战场。同样一次提交就能收多次数据,特别适合大流量网络应用。
  • 6.x系列:被广泛认为是生产环境的最佳选择。bug更少、安全补丁及时、性能调优到位。
如果你还在用5.x早期版本,很多现代高性能应用的例子代码可能跑不起来。所以,强烈建议直接升级到最新的LTS内核(比如6.6或6.8),既稳又快。

📚 好帮手登场:liburing让编程变得丝滑

直接操作iouring的原始系统调用(iouringsetup、iouringenter、iouringregister)虽然灵活,但代码会写得又臭又长。社区大神Jens Axboe(iouring的作者本人)维护了一个叫liburing的用户空间库,几乎成了事实标准。

用liburing,你只需要几行代码就能搭建一个完整的异步I/O循环。它还提供了向后兼容层,即使你的内核版本低一些,也能尽量用上可用功能。几乎所有现代异步框架(比如libuv的升级版、Rust的tokio等)背后都在悄悄用它。

⚠️ 小心地上的“香蕉皮”:资源限制与运行时配置

iouring强大,但也不是没有代价。

首先是注册缓冲区(registered buffers)。如果你想用固定缓冲区避免每次拷贝(类似DMA),这些缓冲区会被锁定在物理内存里,受RLIMIT_MEMLOCK限制。普通用户默认只有64KB,远不够用,得提前ulimit调高。每个缓冲区最大1GiB,且必须是匿名内存(malloc或MAPANONYMOUS),不能是文件映射的。

其次,系统管理员可能通过sysctl kernel.io_uring_disabled把整个功能关掉(值为1或2)。生产环境部署前务必检查一下,免得上线才发现“车站被锁了”。

🛡️ 安全这回事:性能与风险的平衡

iouring引入了新的系统调用和共享环机制,曾经被发现过几个比较严重的漏洞(比如缓冲区溢出导致提权)。因此,很多云厂商和安全强化发行版默认禁用了它,或者只允许特权用户使用。

建议:

  1. 始终使用最新稳定内核,及时打安全补丁。
  2. 在容器环境里,如果不需要,可以通过seccomp或capabilities限制。
  3. 监控CVE公告,尤其是iouring相关的。

性能虽好,安全不能丢。

🌐 适用场景与兼容性小贴士

iouring在块设备(NVMe SSD)、网络socket上表现最佳,能轻松把单线程I/O吞吐量提升数倍到数十倍。但在某些老文件系统(如ext4)上,元数据操作仍可能阻塞线程——这不是iouring的锅,而是文件系统本身的限制。

它完美取代了旧的POSIX AIO(那个东西对socket支持极差),也比epoll+非阻塞I/O更高效。现代高性能应用(云存储、数据库、CDN、游戏服务器)几乎都在转向iouring。

如果你在Docker、Kubernetes或虚拟机里跑,记得检查宿主机的内核版本和配置。有时容器里看到的uname -r是宿主机的,但功能可能被namespace隔离限制。

🎯 最后的话:拥抱未来的I/O方式

iouring不再是一个小众玩具,它已经成了Linux高性能I/O的标杆。从5.1的初出茅庐,到如今6.x的成熟稳健,它像一条不断延伸的高速公路,把应用程序与底层存储、网络之间的延迟和开销压缩到了极致。

无论你是写一个高并发Web服务器,还是搞一个低延迟的数据库缓存,都值得花时间去学它、用它。未来几年,随着更多特性落地(比如零拷贝网络、直接I/O优化),iouring只会越来越强大。

所以,下次当你的程序因为I/O卡顿而喘不过气时,别再一味加线程、加机器了。试试iouring吧——它可能就是你性能翻倍的“作弊码”。


参考文献

  1. Jens Axboe. iouring - a modern asynchronous I/O interface for Linux. Linux Kernel Documentation, 2024.
  2. Red Hat Enterprise Linux 9.3 Documentation - Performance and Feature Guide for iouring.
  3. Linux Kernel Changelog - iouring related entries from 5.1 to 6.8.
  4. liburing official repository and man pages (https://github.com/axboe/liburing).
  5. Kernel configuration options reference - CONFIGIO_URING and related security considerations.

讨论回复

2 条回复
✨步子哥 (steper) #1
01-18 03:07

Java的异步觉醒:iouring如何悄然重塑高并发帝国的命运

想象一下,你是一位掌管百万级并发帝国的服务器君主。成千上万的虚拟线程如轻盈的信鸽般飞来飞去,却在读取文件或网络数据时,突然被沉重的铁链——传统的阻塞I/O——死死钉在原地。载体线程无法脱身,整个王国瞬间拥堵不堪。这正是过去几年Java开发者最头疼的场景,直到一个来自Linux内核深处的“暗影忍者”——iouring——登场。它以近乎零系统调用的优雅身姿,承诺让这一切成为历史。今天,我们就来讲述这个异步革命的故事:它如何在Java世界悄然发酵,又如何在2026年初的此刻,依然在原生JDK与第三方库之间上演一场精彩的拉锯战。

🌌 内核深处的双环魔法:iouring的诞生与奥秘

故事要从2019年的Linux内核5.1说起。那一年,一个全新的异步I/O接口——iouring——横空出世。它不像传统的epoll只擅长网络,也不像POSIX AIO只照顾文件,而是用两个共享内存环形缓冲区(submission queue和completion queue)统一了几乎所有I/O类型。用户态把请求批量塞进提交队列,内核处理完再把结果放进完成队列,整个过程可以做到“零系统调用”——是的,你没听错,零!

iouring的核心创新在于“共享环缓冲区”机制。传统I/O每次操作都要陷入内核(syscall),来回切换开销巨大。而iouring让用户态和内核态共享内存,只需偶尔通过一次syscall刷新指针,就能批量提交和收获结果。这就像快递公司不再为每一件包裹单独跑一趟,而是用一个大信箱,你把包裹全塞进去,快递员一次性取走、一次性送回。
这种设计让iouring在高并发场景下表现出色:支持多shot持久接受/接收(内核5.19+)、零拷贝网络传输、甚至对本地文件也能大幅降低上下文切换。基准测试显示,在Web服务器、数据库等I/O密集型负载中,它往往能带来2-10倍的吞吐提升。当然,前提是你的内核版本足够新(至少5.1,最好6.0+),否则许多高级特性会悄然缺席。

🔗 为什么Java如此渴望iouring的拥抱?

Java从JDK 1.4的NIO开始,就一直在追逐异步梦想。但传统阻塞I/O有一个致命问题:在Project Loom的虚拟线程时代,一个虚拟线程一旦调用阻塞的文件读写,就会“钉死”(pin)其载体线程,导致整个ForkJoinPool的调度效率雪崩。Loom的作者Ron Pressler曾在文档中直言:如果文件I/O继续阻塞,虚拟线程的“百万并发”承诺就只是漂亮的广告词。

iouring的出现恰逢其时。它能让文件I/O真正异步,载体线程无需等待,直接去侍奉其他虚拟线程。这意味着我们终于可以写出“看起来完全阻塞、实际完全不阻塞”的代码——这正是Loom追求的终极优雅。网络方面,虽然NIO+epoll已经不错,但iouring的多shot和零拷贝特性仍能进一步榨取性能,尤其在高连接数场景下。

想象你正在开发一个云原生微服务:数以万计的虚拟线程同时从磁盘读取配置、日志、模型文件。如果用传统方式,载体线程很快就会被耗尽;但换上iouring,它们就像用上了隐身术,轻盈地掠过I/O瓶颈,继续处理下一个请求。

🛠️ 原生JDK的漫长等待:2026年初的真实现状

截至2026年1月,标准JDK仍然没有直接暴露iouring API。Project Loom虽然从JDK 21就稳定了虚拟线程,但文件I/O依然依赖“ManagedBlocker”机制:当阻塞发生时,Loom会动态向ForkJoinPool注入额外的OS线程来补偿。这种方案能用,但效率远不如原生iouring——毕竟额外线程的创建和调度本身就是开销。

OpenJDK社区有一个sandbox分支(https://github.com/openjdk/jdk-sandbox/tree/iouring)正在实验性地用Project Panama直接调用iouring,目标是彻底消除文件I/O的pinning问题。然而这个分支仍处于早期阶段,尚未进入主线。JDK 25(2025年9月发布)没有包含它,JDK 26(预计2026年3月GA)在2025年12月的特性冻结清单中也未见踪影。社区讨论显示,最大的技术难点在于iouring的“完成模型”(completion-based)与传统Selector的“就绪模型”(readiness-based)如何优雅融合。

简单来说:短期内(JDK 26、27),我们大概率还得继续等待;中长期(2027年后),随着Panama与Loom的进一步协同,iouring很可能成为Linux下文件I/O的默认后端。那时,写一个普通的Files.readAllBytes()可能就自动享受到异步福利,而开发者几乎无需改动代码。

📚 第三方库的繁荣时代:今天就能吃到的性能红利

好消息是,我们并不需要坐等Oracle。凭借Project Panama(JDK 22正式版)的Foreign Function & Memory API,一批高质量的iouring绑定库已经成熟,让开发者现在就能在生产环境使用它们。

我们来看几个代表性选手(以下表格汇总了2026年初的主流选择):

库名称主要专注领域绑定方式最低JDK要求亮点特性项目地址当前状态(2026年初)
JUring文件I/OPanama22+与虚拟线程深度整合,顺序读可达10倍加速https://github.com/davidtos/JUring活跃开发,基准数据亮眼
Netty io_uring网络I/O原生(incubator)8+(推荐22+)多shot polling、TCP FastOpen,支持Vert.xhttps://github.com/netty/netty-incubator-transport-io_uring成熟,已修复JDK 24+ Unsafe兼容性问题
jasyncfio文件I/OJNI17+固定缓冲区异步读写https://github.com/ilyakorennoy/jasyncfio稳定,但性能逊于Panama方案
io_uring-java通用I/OPanama/JNI22+模式驱动的绑定生成https://github.com/ChinaXing/io_uring-java早期阶段,潜力可期
Jliburing低级封装JNI11+直接封装liburinghttps://github.com/Sammers21/Jliburing维护模式

其中,JUring是最值得关注的黑马。它专为虚拟线程设计,基准测试显示在顺序读取大文件时,比传统RandomAccessFile快10倍以上——原因正是极大地减少了系统调用次数。Netty的iouring transport则在网络侧大放异彩,许多Vert.x用户已将其设为首选后端(如果内核支持的话,否则自动降级到epoll)。

这些库的出现,意味着即使原生JDK迟迟不动,我们也能在文件密集型应用(如日志处理、配置加载、ML模型加载)或网络密集型应用(如API网关、消息队列)中立即获得显著性能提升。

⚖️ 性能真相与隐藏的代价:不是所有场景都适合

iouring固然强大,但并非银弹。一些真实世界的测试揭示了有趣的现象:

  • 在禁用Netty auto-read的场景下,iouring有时反而比epoll慢——因为它引入了内部线程池来处理某些阻塞操作,与Loom的补偿机制产生了重叠。
  • 对于本地磁盘文件,如果底层存储本身是瓶颈(比如机械硬盘),iouring的系统调用节省带来的收益会被磁盘寻道时间完全掩盖。
  • 配置敏感性极高:队列深度(SQE/CQE大小)、是否开启IOPOLL、是否使用多shot,都可能导致性能从“起飞”到“坠机”的戏剧性反转。
因此,正确的做法是:先在目标内核(推荐6.0+)上做针对性基准,再决定是否切换。许多团队的经验是——网络I/O几乎总是受益,而文件I/O则需要看具体负载模式。

🔮 未来的星辰大海:当Loom与iouring终于合体

展望2027年以后,随着Panama的继续演进和Loom对文件系统可扩展性的持续投入,我们很可能看到一个“统一异步I/O时代”的到来:开发者只需写最简单的阻塞式代码,JDK在Linux下自动选择iouring后端,在其他平台优雅降级。那时,Java的百万虚拟线程将不再是纸面数字,而是真正可落地的高并发生产力。

到那时,回望2026年的今天,我们会感慨:原来那段“库驱动的过渡期”恰恰是最激动人心的探索阶段——开发者们用JUring、Netty等先锋武器,提前品尝到了异步革命的果实。

无论你是刚刚接触虚拟线程的新手,还是已经在高并发战场厮杀多年的老将,iouring都值得你立刻动手实验。它不仅是性能工具,更是Java生态向现代系统编程迈进的重要一步。去试试吧,让你的服务器王国真正摆脱阻塞的枷锁,迎来真正的轻盈与自由。


参考文献

  1. JUring GitHub Repository. https://github.com/davidtos/JUring
  2. Phoronix: JUring Experimental IOuring for Java. https://www.phoronix.com/news/JUring-IOuring-Java
  3. Red Hat Developer: Why Use iouring for Network I/O. https://developers.redhat.com/articles/2023/04/12/why-you-should-use-iouring-network-io
  4. OpenJDK Loom Project State Document. https://cr.openjdk.org/~rpressler/loom/loom/sol1part1.html
  5. InfoWorld: Project Loom – Understand the New Java Concurrency Model. https://www.infoworld.com/article/2334607/project-loom-understand-the-new-java-concurrency-model.html

✨步子哥 (steper) #2
01-18 03:08

Go语言与iouring的奇妙邂逅:一场异步I/O的高速追逐战

想象一下,你是一位忙碌的快递站站长,每天要处理成千上万的包裹。传统的做法是:每次有包裹来,你得亲自跑去门口签收(系统调用),然后再跑回去分拣(上下文切换),忙得团团转。而突然有一天,有人发明了一种神奇的环形传送带——包裹直接从用户区滑到内核区,你只需在传送带两端放好请求和结果,就能批量处理一切。这就是iouring带来的革命。它不是简单的优化,而是Linux内核对异步I/O的一次彻底重构,让高并发场景下的性能像坐上了火箭。

🚀 iouring的诞生:从痛点到奇迹的飞跃

iouring从Linux内核5.1版本(2019年)正式登场,由大名鼎鼎的块层维护者Jens Axboe主导开发。它解决了一个长期困扰开发者的难题:传统异步I/O(如epoll + aio)需要多次系统调用、频繁的就绪通知、大量的上下文切换,尤其在高并发网络服务器或海量文件操作时,CPU就像被堵在早高峰的公路上,动弹不得。

iouring的核心设计可以用一个生动比喻来形容:它在用户空间和内核空间之间架设了两个共享的环形缓冲区——提交队列(SQ)完成队列(CQ)。你把I/O请求像信封一样塞进SQ,内核批量取走执行;执行完毕后,结果直接丢进CQ,你随时去取即可。整个过程几乎零拷贝、零锁、批量提交,系统调用次数大幅减少。

环形缓冲区的奥秘 环形缓冲区就像一个圆形传送带,头尾相连,避免了线性队列的频繁内存移动。SQ用于提交请求,CQ用于接收完成事件。两者通过内存映射(mmap)共享,无需每次进入内核态拷贝数据。这让iouring在高负载下能轻松处理数十万甚至上百万的并发连接,而传统epoll在类似场景下往往会喘不过气。
尤其在网络I/O上,从内核5.5开始逐步完善固定缓冲区、零拷贝发送等特性,到5.8+已相当成熟。简单来说,iouring把“通知式”(epoll告诉你“数据准备好了”)变成了“完成式”(内核直接告诉你“操作做完了,结果在这儿”),省去了大量轮询开销。

🌪️ Go语言的尴尬处境:原生支持为何迟迟不来?

Go语言以简洁、高并发著称,其runtime调度器(基于epoll/kqueue/iouring的Windows版iocp)让数以万计的goroutine轻量切换,仿佛一场优雅的芭蕾舞。然而,截至2026年1月,Go的标准库和runtime仍然没有原生集成iouring

为什么?原因可以追溯到Go调度器的设计哲学。Go的netpoller深深嵌入runtime中,它假设I/O操作会阻塞当前M(机器/线程),从而让出CPU给其他goroutine。如果直接换成iouring,调度器需要感知“这个goroutine其实没阻塞,只是提交了请求”,否则会错误地挂起或唤醒,破坏整个协程模型。社区早在2019年就开了issue #31908讨论透明集成,但多年来进展缓慢——Go团队更倾向于保守,确保跨平台一致性,而不是为Linux独享的特性大动干戈。

这就像一辆设计完美的跑车(Go runtime),突然有人想换上喷气引擎(iouring)。不是不能换,而是要重新设计底盘、变速箱、刹车系统,工程量巨大。目前,Go在Linux上依然忠实地使用epoll,性能虽优秀,但在极端高并发(如百万连接)场景下,与原生iouring的应用相比仍有差距——某些基准显示落后30%-50%。

🔧 第三方库的百花齐放:Go社区的救赎之路

好消息是,Go社区从不缺能人。开发者们纷纷卷起袖子,用CGO或纯Go实现了多种iouring桥接库,让我们能在Go中提前享受到这份“高速快感”。以下是目前主流且相对活跃的几个选择(按综合评价排序):

库名称GitHub仓库主要特性状态与适用场景
gainpawelgaczynski/gain全纯Go实现的高性能网络框架,专为io_uring优化,支持零拷贝、固定缓冲区等高级特性最活跃,适合构建高吞吐网络服务(如HTTP服务器)
iouring-go (Iceber)Iceber/iouring-go易用异步接口,支持文件/套接字IO、超时、链接请求、固定缓冲区,带中文文档活跃,文档友好,上手最快,推荐新手入门
go-uringgodzie44/go-uring几乎完整移植liburing,提供低级API + Reactor事件循环,支持网络优化功能全面,适合需要深度控制的项目
iouring-go (hodgesds)hodgesds/iouring-go类似liburing的封装,支持基本操作,WIP状态但接受PR适合POC和贡献者,社区活跃
uring (纯Go)github.com/y001j/uringnet/uring无CGO纯Go实现,支持异步IO,依赖较新内核特性适合追求纯Go、无外部依赖的项目

这些库各有千秋。举个例子,使用Iceber/iouring-go写一个简单文件写入,只需几行代码就能异步提交,感受不到传统Write的阻塞感。而gain框架则更进一步——它直接提供了类似net/http的API,你可以用几乎相同的代码写出比标准库快得多的服务器。

想象你正在开发一个百万连接的聊天服务器。使用标准net包,epoll在高负载下CPU占用飙升;而切换到gain后,同样的硬件能多扛30%-50%的连接,延迟更低,感觉就像给服务器打了肾上腺素。

性能大比拼:iouring在Go中到底有多快?

实测数据表明,iouring在批量操作和大并发场景下优势明显:

  • 网络吞吐:某些基准中,iouring版服务器比epoll版快40%以上,尤其在小包高并发时。
  • 文件I/O:大文件顺序读写接近裸金属性能;随机读写在多线程下因减少锁竞争而大幅领先。
  • 极限测试:有开发者用gain实现echo服务器,在相同硬件上QPS轻松突破百万,而标准库往往在70-80万附近开始抖动。
当然,不是所有场景都适合。小文件、单线程、低并发时,iouring的环初始化开销可能略高于传统阻塞I/O。但一旦进入高负载区,它就像高速列车甩开普通汽车——差距越来越大。
为什么不是处处碾压? iouring需要内核支持完整特性(推荐5.8+),早期版本缺少网络零拷贝、多shot操作等。并且,第三方库目前无法与Go调度器完美融合,goroutine仍可能在等待完成事件时被挂起,损失部分轻量优势。这也是社区期待原生支持的根本原因。
🛠️ 上手指南:如何在你的Go项目中拥抱iouring
  1. 先检查环境
运行uname -r确认内核版本≥5.8,最好是5.19+以获得最佳特性。
  1. 选择库起步
- 新手推荐Iceber/iouring-go:go get github.com/Iceber/iouring-go,文档详尽,有完整示例。 - 追求极致网络性能选gain:直接用它替换net/http,改动最小。 - 需要底层控制选go-uring:可以自己实现事件循环。
  1. 小步快跑
先在非核心模块实验(如日志写入、静态文件服务),验证稳定性后再逐步迁移。
  1. 监控与调优
使用io_uring_enter系统调用监控工具,或perf分析SQ/CQ使用率,避免队列溢出。

🎭 未来的期待:Go与iouring会修成正果吗?

社区的呼声从未停止。每次Go发布周期,总有人在issue里追问进度。虽然Go团队保持谨慎,但随着iouring在Rust、Zig、Java(Project Loom)等语言中开花结果,Go若继续缺席,可能在某些性能敏感领域逐渐失势。或许在Go 1.28或1.30,我们就能看到runtime悄然切换到iouring的那一天。

到那时,Go的goroutine将真正如虎添翼——轻量、零开销、原生异步。就像这场异步I/O的追逐战终于迎来大团圆:Go语言不再是旁观者,而是主角。


参考文献

  1. Jens Axboe. iouring - a new asynchronous I/O interface for Linux. kernel.org, 2019-2026持续更新。
  2. Go Issue #31908: internal/poll: transparently support new linux iouring interface. golang/go, 2019-2026.
  3. pawelgaczynski/gain: High-performance iouring networking framework in pure Go. GitHub, 2024-2026活跃维护。
  4. Iceber/iouring-go: Easy-to-use async IO interface with comprehensive Chinese documentation. GitHub, 2025最新提交。
  5. Community benchmarks and discussions on iouring vs epoll in Go applications, collected from Reddit r/golang and various technical blogs, 2023-2026.