
下面是一个完整的 Swooleio_uring 案例涵盖 HTTP 服务器、协程文件 I/O 和并发请求三个场景。---ns)环境要求-Linux kernel5.7支持 IORING_FEAT_FAST_POLL-Swoole5.0或 OpenSwoole26.2.0-编译时加--enable-uring_sock # 编译安装 Swoole启用 io_uring pecl install swoole # 或源码编译./configure--enable-uring_sock--enable-openssl makemake install---案例1io_uring HTTP 服务器协程文件读取?php// server.php// io_uring 在 reactor 层透明生效代码写法与普通 Swoole 一致// 差异在于内核层用 io_uring 替代 epoll减少系统调用开销use Swoole\Http\Server;use Swoole\Http\Request;use Swoole\Http\Response;use Swoole\Coroutine;$servernewServer(0.0.0.0,9501,SWOOLE_PROCESS);$server-set([worker_numswoole_cpu_num(),enable_coroutinetrue,hook_flagsSWOOLE_HOOK_ALL,// 协程化所有 I/O// io_uring 通过编译选项启用运行时无需额外配置]);$server-on(request,function(Request $req,Response $res){$path$req-get[file]??/etc/hostname;// 协程文件读取 —— OpenSwoole 26.2 底层走 io_uring 异步文件 I/O$contentCoroutine\System::readFile($path);if($contentfalse){$res-status(404);$res-end(file not found);return;}$res-header(Content-Type,text/plain);$res-end($content);});$server-start();---案例2io_uring 并发文件批量读取对比 epoll 优势场景?php// batch_read.php// io_uring 的核心优势批量提交 I/O 请求减少 syscall 次数use Swoole\Coroutine;use Swoole\Coroutine\WaitGroup;Coroutine\run(function(){$files[/etc/hostname,/etc/os-release,/proc/version,/proc/cpuinfo,/proc/meminfo,];$wgnewWaitGroup();$results[];$startmicrotime(true);foreach($files as $i$file){$wg-add();Coroutine::create(function()use($file,$i,$wg,$results){// 每个协程独立发起文件读取// io_uring 将这些请求批量提交到内核 submission queue// 避免每次 read() 都陷入内核减少 context switch$results[$i][file$file,sizestrlen(Coroutine\System::readFile($file)?:),coroutineCoroutine::getCid(),];$wg-done();});}$wg-wait();$elapsedround((microtime(true)-$start)*1000,2);echo并发读取 .count($files). 个文件耗时 {$elapsed}ms\n\n;foreach($results as $r){printf( [cid%d] %-20s %d bytes\n,$r[coroutine],$r[file],$r[size]);}});---案例3io_uring TCP 服务器socket 层?php// tcp_server.php// --enable-uring_sock 让 TCP socket 的 accept/recv/send 走 io_uringuse Swoole\Server;$servernewServer(0.0.0.0,9502,SWOOLE_PROCESS,SWOOLE_SOCK_TCP);$server-set([worker_num4,enable_coroutinetrue,open_length_checkfalse,]);$server-on(connect,fn($s,$fd)printf([%d] client connected\n,$fd));$server-on(receive,function(Server $s,int $fd,int $rid,string $data){// io_uring: recv 和 send 通过 SQE/CQE 环形队列处理// 高并发下比 epollread/write 减少约 30% 的系统调用$responsestrtoupper(trim($data)).\n;$s-send($fd,$response);});$server-on(close,fn($s,$fd)printf([%d] client closed\n,$fd));$server-start();---验证 io_uring 是否生效 # 运行服务后用 strace 观察系统调用 strace-ppid-e traceio_uring_enter,io_uring_setup21|head-20# 或查看/proc/pid/fdinfo 中的 io_uring fd ls-la/proc/pid/fd|grep anon_inode # 压测对比需要 wrk wrk-t4-c200-d10s http://127.0.0.1:9501/---关键原理 epoll 模型:用户态 →epoll_wait()→ 内核通知 →read()/write()→ 用户态 每次 I/O至少2次 syscall io_uring 模型:用户态 → 写入 SQ ring → 内核消费 → 写入 CQ ring → 用户态读取 批量 I/O1次io_uring_enter()提交 N 个请求 FAST_POLL 模式下热路径甚至0次 syscall io_uring 对 Swoole 的提升主要体现在高并发文件 I/O绕过线程池和大量短连接 TCP减少 epoll_ctl 调用。协程 API 完全不变升级成本为零。