Swoole 重新定義了 PHP 的效能邊界,提供生產級的異步非阻塞 I/O、協程、多進程/執行緒能力。本文通過實戰代碼與壓測數據,展示 Swoole 如何將 PHP 從傳統同步阻塞模型解放出來。
<?php
// 簡單的 Swoole HTTP 伺服器
$server = new Swoole\Http\Server("0.0.0.0", 9501);
$server->on("request", function ($request, $response) {
// 模擬業務邏輯:資料庫查詢 + 模板渲染
$data = createModel('UserInfo')->get(12)->get();
$html = $this->swoole->tpl->fetch('test.html');
$response->end($html . $this->showTime());
});
$server->start();
| 模式 | QPS (單進程) | QPS (4進程) | 平均延遲 |
|---|---|---|---|
| Swoole EventTCP | 571.70 | 1153.63 | 0.87ms |
| Swoole SelectTCP | 659.01 | 1010.08 | 0.99ms |
| Swoole BlockTCP | 561.24 | 1094.58 | 0.91ms |
| Apache Prefork | 80.57 | — | 12.41ms |
結論:Swoole 單進程效能約為 Apache 的 7 倍,多進程模式下優勢更明顯,延遲降低 10 倍以上。
<?php
// 協程寫法:同步語法,異步執行
go(function () {
$mysql = new Swoole\Coroutine\MySQL();
$mysql->connect([
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => 'pass',
'database' => 'test',
]);
$result = $mysql->query("SELECT * FROM users LIMIT 10");
var_dump($result);
});
// 並發執行多個查詢
$channels = [];
for ($i = 0; $i < 10; $i++) {
$chan = new Swoole\Coroutine\Channel(1);
go(function () use ($chan, $i) {
$mysql = new Swoole\Coroutine\MySQL();
$mysql->connect($config);
$result = $mysql->query("SELECT SLEEP(1), $i as id");
$chan->push($result);
});
$channels[] = $chan;
}
// 等待所有完成(總耗時 ~1秒,而非 10秒)
foreach ($channels as $chan) {
$result = $chan->pop();
var_dump($result);
}
Swoole\Runtime::enableCoroutine() 一鍵協程化傳統阻塞代碼opcache、swoole.use_shortname=Off 提升效能| 問題 | 解決方案 |
|---|---|
| 全域變數汙染 | 協程間隔離,避免使用 $GLOBALS、靜態屬性存儲請求級數據 |
| 阻塞函數調用 | 使用協程版客戶端或 Runtime::enableCoroutine() |
| 記憶體洩漏 | 及時釋放大對象、關閉連接、設置 max_request 重啟工作進程 |
| 死鎖風險 | Channel 操作設置超時、避免巢狀等待 |
Swoole 讓 PHP 具備了與 Node.js、Go 競爭高併發場景的實力。掌握協程程式模型,是釋放 Swoole 潛能的關鍵。