我构建了世界上最快的 PHP 网络服务器
I built the fastest PHP webserver in the world

原始链接: https://qbixserver.com

大多数 PHP 环境依赖阻塞式 I/O,由于运行多个工作进程(worker)会带来高昂的内存开销,这在传统上限制了其扩展性。虽然 Swoole、FrankenPHP 和 RoadRunner 等解决方案试图解决这一问题,但在处理现有代码库时仍面临局限。 Qbix 引入了一种利用 `pcntl_fork()` 系统调用的高效替代方案。通过在派生进程(fork)之前将应用程序框架加载到父进程中,服务器利用了 Linux 内核的“写时复制”(COW)内存管理机制。这使得数千个工作进程能够共享同一内存空间,仅在处理特定请求时对修改的数据消耗额外的内存。 这种方法改变了 PHP 扩展的经济性:开发者不再受限于少量资源密集型工作进程(如 PHP-FPM),而是能以极低的成本启动数千个工作进程。由于该系统能在此规模下有效处理阻塞式 I/O,因此无需特殊的扩展或复杂的异步编程。Qbix 通过标准的纯 PHP 代码,有效地实现了高性能并发。

最近一场 Hacker News 的讨论聚焦于“Qbix”。这是一个完全用 PHP 编写的 Web 服务器,声称通过使用“分叉后(post-fork)”内存模型,其性能显著优于 PHP-FPM 等传统架构。 **主要主张与功能:** * **性能:** 通过在预加载类后使用 `pcntl_fork`,工作进程仅占用极少内存(低至 140KB),使单台机器处理的并发进程数比标准 PHP-FPM 高出 100 倍。 * **兼容性:** 声称支持现有的、未经修改的 PHP 应用程序(包括 Laravel 和 WordPress 等框架),无需将代码重写为异步风格。 * **一体化:** 内置对 WebSockets、实时聊天室、定时任务和 TLS 管理的支持,理论上消除了技术栈中对 Nginx、Redis 或 Node.js 的需求。 **社区反应:** 反馈呈两极分化。支持者称赞其简化技术栈和依赖管理的愿景。然而,许多批评者表示怀疑,质疑该自研 Web 服务器的稳定性和安全性。讨论中有很大一部分集中在该项目的文档和营销上;许多用户认为这些内容大量由大语言模型(LLM)生成,从而引发了关于“LLM 生成”软件项目的价值,以及企业级 Web 服务器加固重要性的辩论。
相关文章

原文

The vast majority of PHP code — WordPress plugins, Laravel packages, every PDO::query() and file_get_contents() ever written — uses blocking I/O. Swoole’s coroutines can’t help with code that doesn’t yield. FrankenPHP and RoadRunner use the same worker-count-limited model as fpm.

Qbix takes a different approach: run many workers. The server loads your entire framework into a parent process, then calls pcntl_fork() to create workers. The kernel marks the parent’s pages copy-on-write. Workers share every loaded class — they only pay for pages they actually write to during the request.

A WordPress-like request dirties 30 pages = 120KB on Linux. So 200MB doesn’t buy 4 workers (like fpm) — it buys thousands. Each one blocks on its database query, and that’s fine. Blocking I/O doesn’t matter when you have enough workers. COW is what makes “enough workers” cost 47MB instead of 16GB.

This is pure userland PHP. No kernel module, no C extension, no custom allocator. Just pcntl_fork() after loading everything, and the OS does the rest.

We proposed this for PHP core as switch_global_context(). While that works its way through the RFC process, the server does it in userland today.

联系我们 contact @ memedata.com