HN 日本語サマリー

← 一覧へ戻る
プログラミング

世界最速のPHPウェブサーバーを構築した

I built the fastest PHP webserver in the world (qbixserver.com)

31 pointsby EGreg28 コメント

要約

開発者は、Swoole、FrankenPHP、RoadRunnerといった既存のソリューションよりも高速であると主張する、純粋なPHPで書かれた新しいウェブサーバー「Qbix」を発表しました。このサーバーは、PHPのコードを一切変更せず、追加の拡張機能やDockerも不要で、単一のファイルまたはバイナリとして動作します。大量のワーカープロセスを効率的に管理するCopy-on-Write(COW)メモリ共有技術により、低メモリフットプリントで高いスループットを実現します。

全文翻訳

Qbix Server: 世界最速のPHPウェブサーバー

[画像: Qbix]Server

[画像]

1台のマシンで100倍のユーザーを処理

OSレベルのプロセス分離により、すべてのHTTPリクエストとWebSocketルームをデフォルトで安全に処理します。PHPの共有なしアーキテクチャに基づいたQbix Serverは、数千の既存PHPウェブサイト★を修正なしで実行できます。現在、Linux、Mac、Windows、iOS、Androidで動作し、署名および配布可能なスタンドアロンバイナリを生成できます。さらに、v2ではアプリを分散化し、Wi-FiとBluetooth経由でオフラインでも作業を継続することが容易になりました。🤯

★ WordPress、OwnCloud、Magento、Drupal、Joomla、およびQbix、Laravel、Symfonyなどのフレームワークが含まれます。

git clone https://github.com/Qbix/webserver
cd webserver
php qbixserver.php

または、自己完結型バイナリ(Linux、macOS、Windows)を入手してください

curl -LO https://github.com/Qbix/webserver/releases/latest/download/qbixserver-macos-arm64
chmod +x qbixserver-macos-arm64
./qbixserver-macos-arm64

すべてを1つのプロセスで

nginx + fpm + Node + Redis + supervisor + Dockerを置き換えます。

⚡

スループット14倍

ワーカーあたり120KBの永続ワーカー。200MBで400ワーカー。fpmが78のところ、1,060 req/s。

詳細はこちら →

🔌

WebSocket + ルーム

HTTPと同じポート。ルームは共有状態を持つフォークされたプロセスです。Socket.IOプロトコル。Node不要。

詳細はこちら →

🧩

未変更のPHP

WordPress、Laravel、Symfony、Drupal。27の関数がファイルロードとして書き換えられています。.htaccessを読み込みます。そのまま動作します。

詳細はこちら →

🔒

マイクロサービス分離

設定変更1つで権限とサンドボックス化。同じコード、異なる役割。シークレットは権限から漏れません。

詳細はこちら →

🌐

クラスターレプリケーション

SQLiteを使用した複数のサーバー。イベントがレプリケートされます。ノードを停止し、再起動すると、キャッチアップします。

詳細はこちら →

🖼️

画像処理

?w=400でリサイズ。AcceptヘッダーからAVIFまたはWebPを提供。Save-Dataサポート。元の画像が変更されたときに再生成されるディスクキャッシュ。

詳細はこちら →

📋

スマートレスポンスヘッダー

コンポーネントごとの無効化のためのX-Cache-Tree。アクセス制御されたファイルのためのX-Accel-Redirect。ETag生成。ディレクトリリスティング。

詳細はこちら →

📈

自動生成APIドキュメント

ハンドラーファイルを記述すると、OpenAPI 3.1およびMCP仕様が自動的に生成されます。Swagger UI、Postman、Redoc — そしてAIツールがアプリのAPIに直接呼び出し可能になります。

詳細はこちら →

🔐

TLS、Cron、ロギング

証明書が存在する場合、HTTPSが自動的に開始されます。組み込みのcronスケジューラ。バッファリングされたアクセスログは、日次ローテーションとgzipアーカイブを備えています。

詳細はこちら →

さらに、チャット、カンバン、SSEストリーム、REST API、ライブカウンター、分散スウォームの6つのサンプルアプリが含まれています。例を見る →

v2.0の新機能

オフラインでも動作し続けるアプリ

すべてのQbix Serverは暗号学的IDを持ち、BluetoothおよびWi-Fi経由で近くの他のサーバーを見つけることができます。同じバスや同じ建物にいる、または信号のない場所にいる電話は、中央サーバーなしで、エンドツーエンドで暗号化され、直接データを交換できます。

//ピアの出現と消失に反応
Q_WebServer_Transport::onPeerOnline(function ($peer) {
    Q_WebServer_MeshSync::syncWithPeer('notes', $peer['peer_id'], $since,
        array('Q_WebServer_Transport', 'requestFromPeer'));
});

v1.xからの破壊的変更はありません。メッシュレイヤーはピアが検出されるまで何も行いません。リリースノート →

fpm(50ms I/O)比14倍

fpm(200ms I/O)比24倍

ワーカーあたり120KB(COW)

状態リセット0.03ms

💡 なぜ他のすべてよりも高速なのか

php-fpmの問題点: opcacheが有効かどうかにかかわらず、本番PHPコードの大部分はI/Oバウンドです。ワーカーはデータベース、ファイルシステム、API呼び出しを待ちます。その待ち時間中、ワーカーは何もしていませんが、30〜60MBのRAMを占有しています。4GBサーバーでは、fpmはせいぜい80ワーカーしか得られません。それぞれが200msのクエリでブロックされます。それが限界です。

Swoole、RoadRunner、FrankenPHPの問題点: これらはPHPをNode.jsのようにイベント駆動にすることで解決しようとします。しかし、それは彼らの非同期ライブラリを使用するようにコードを書き直すことを意味します。すべてのWordPressプラグインやLaravelパッケージのPDO::query()、file_get_contents()、curl_exec()はブロッキングI/Oを使用します。それは譲歩しません。Swooleは協力しないコードを助けることはできません。

Qbixの解決策: 各ワーカーにもっと多くのことをさせるのではなく、より多くのワーカーを実行します。サーバーはフレームワークを親プロセスにロードし、pcntl_fork()を呼び出します。カーネルはすべてのページをコピーオンライト(COW)としてマークします。各ワーカーは親のロードされたクラスを共有し、書き込んだページのみを負担します。WordPressのようなリクエストは30ページを汚染します = 120KB。fpmが80ワーカーを得るのと同じ4GBで、Qbixは数千のワーカーを得ます。

コードは2つのモードで変更なしで実行されます:

永続ワーカー(デフォルト) — ワーカーはリクエスト間で生存します。27の関数がファイルロードとして書き換えられています。静的プロパティは0.03msでスナップショットから復元されます。これは高速パスです:CPUバウンドな作業で2,294 req/s。

リクエストごとのフォーク — シムが追跡できないコード(内部静的変数を持つ関数、追跡不可能なグローバル状態を登録するプラグイン)用。各リクエストは新しいフォークを取得します。永続モードより遅いですが、各ワーカーのコストは依然として120KBであり、50MBではありません — そのため、同じハードウェアでfpmよりも100倍多くのワーカーを実行できます。それがすべてです。

Windowsでも — フォークが利用できない場合でも、サーバーは同じ27関数の書き換えで永続ワーカーを実行します。COWメモリの節約はありませんが、同じコード互換性と同じコントロールパネルが得られます。

私たちはこれをPHPコアに提案しました(switch_global_context()として)。それがRFCプロセスを経ていく間、サーバーは今日ユーザーランドでそれを実行します。

🔍 Swoole、FrankenPHP、php-fpmとのベンチマーク

CPUバウンド(WordPress風ワークロード、同じ200MB):

ワーカーreq/sfpm比
php-fpm4~350—
Swoole4~4001.1倍
Qbix1002,2946.6倍

I/Oバウンド(50msデータベースクエリ):

ワーカーreq/sfpm比
php-fpm478—
Swoole (コルーチン*)4~300~4倍
Qbix1001,06014倍

I/Oバウンド(200ms — 実際のデータベース負荷):

ワーカーreq/sfpm比
php-fpm420—
Swoole (コルーチン*)4~200–500~10–25倍
Qbix20048824倍
  • SwooleコルーチンにはRuntime::enableCoroutine()とコルーチン対応ドライバーが必要です。未変更のWordPress/LaravelはブロッキングI/Oを使用し、fpmの限界に達します。

🛡️ 27の関数が書き換えられる — 状態がリセットされる仕組み

ワーカーは永続的で、再起動なしで数千のリクエストを処理します。各リクエスト間、Reflectionベースのスナップショットが0.03msで全静的プロパティを復元します。27のPHP関数は、PHPがコンパイルする前に、各ファイルがロードされるときに書き換えられます:

header(), setcookie(), session_start(), move_uploaded_file(), ini_set(), register_shutdown_function(), set_error_handler(), spl_autoload_register(), putenv(), およびその他の18関数 — これらはすべてリクエストごとに追跡され、リクエスト間にクリーンアップされます。

未変更のWordPress、Laravel、Symfony、Drupalは、共有なしの安全性を自動的に取得します。アダプター不要、コード監査不要。

完全な互換性詳細 → · 各フレームワークで書き換えられるもの →

📊 1台の月額30ドルのマシンでどれだけのユーザーを処理できるか?

メトリックphp-fpmQbix
4GBでのワーカー数~80 (各50MB)400 (各120KB)
スループット (200ms I/O)~80 req/s~2,000 req/s
同時アクティブユーザー1,60040,000
登録アカウント16K–32K400K–800K
WebSocketNode.jsが必要100K+ 組み込み
データベースPostgresが必要SQLite (50K書き込み/秒)
月額コスト$30 + DBサーバー合計 $30

1台のマシン。データベースサーバー、Redis、Node、Dockerなし。冗長性のためにDNSフェイルオーバーを備えた2台目を追加 — 分散モードは両方のSQLiteコピーを同期させ続けます。

事前ロード後のフォーク

すべてを一度ロードします。ワーカーをフォークします。各ワーカーは120KB、42MBではありません。

親プロセス (30MB)フレームワーク · ルート · キャッシュCOWCOWワーカー (120KB)ワーカー (120KB)ワーカー (120KB)ワーカー (120KB)php-fpm: 4 × 42MB = 168MBQbix: 400 × 120KB = 47MB同じコード。同じRAM。100倍のワーカー。

ライブダッシュボード

/Q/dashboardで組み込み。Grafana不要、Prometheus不要。

localhost:4000/Q/dashboard

Qbix Server Dashboard

2,847Req/min

142接続

400ワーカー

23msレイテンシ

99.8%稼働率

47MBメモリ

200 GET /api/users 12ms
200 POST /api/tasks 34ms
304 GET /css/app.css 1ms
200 WS /Q/ws upgrade 2ms

ダッシュボードとコントロールパネルのドキュメント →

開始方法

git clone https://github.com/Qbix/webserver
cd webserver
php qbixserver.php --root=examples/todo/web

GitHubで表示 → バイナリをダウンロード 例

どこでも実行可能

お使いのプラットフォーム用のバイナリをダウンロードしてください。PHPは内部にバンドルされているため、インストールは不要です。

Linuxx86_64 & ARM64 · COWフォーク

macOSApple Silicon & Intel · COWフォーク

Windowsx64 · 永続ワーカー

iOS & Androidarm64 · メッシュトランスポート

LinuxとmacOSでは、約120KBのCOWフォークワーカーが数千。Windowsでは、同じ27関数の書き換えを備えた永続ワーカー。電話では、ネイティブBluetoothおよびWi-Fiトランスポートの背後にある同じサーバー。FreeBSDはソースからビルドします。

既存のコードベースで使用

nginx + php-fpmで実行中のPHPアプリがある場合、切り替えは1コマンドです。

cd my-laravel-app && php qbixserver.php --root=public --preset=laravel
cd my-wordpress-site && php qbixserver.php --root=. --preset=wordpress
cd my-symfony-app && php qbixserver.php --root=public --preset=symfony
cd my-drupal-site && php qbixserver.php --root=web --preset=drupal

まず永続モードを試してください — ほとんどのアプリに対応しています。フォークごとのリクエストが必要な場合でも、同じハードウェアでfpmよりも100倍多くのワーカーを実行できます。コードがどのように書き換えられるか →