以下是 Swoole HTTP 服务中 同步、异步 和 协程 三种模式的对比及示例代码:
一、同步模式(阻塞式)
特点
- 传统 PHP 模式:代码按顺序执行,每个请求独占进程/线程。
- 阻塞 I/O:遇到数据库查询、文件读写等操作时,进程会挂起等待。
- 简单易用:适合简单逻辑或低并发场景。
示例代码
$http = new Swoole\Http\Server('0.0.0.0', 9501);
// 同步模式(默认行为)
$http->on('request', function ($req, $res) {
// 模拟阻塞操作(如查询数据库)
sleep(1); // 这里会阻塞整个 Worker 进程!
$res->end('Sync Response');
});
$http->start();
二、异步模式(非阻塞)
特点
- 事件驱动:通过回调函数处理耗时操作,不阻塞主进程。
- 高性能:适合高并发场景(如大量 I/O 操作)。
- 代码复杂度高:需要处理回调嵌套(Callback Hell)。
示例代码
$http = new Swoole\Http\Server('0.0.0.0', 9501);
$http->on('request', function ($req, $res) {
// 启用异步任务(非阻塞)
$taskId = $http->task([
'type' => 'async_operation',
'data' => $req->get,
]);
// 注册任务完成回调
$http->on('finish', function ($serv, $taskId, $data) use ($res) {
$res->end("Async Response: " . $data);
});
});
// 注册异步任务处理逻辑
$http->on('task', function ($serv, $taskId, $workerId, $data) {
// 模拟异步耗时操作(如 HTTP 请求、Redis 查询)
sleep(1);
return "Result for {$data['type']}";
});
$http->start();
三、协程模式(Coroutine)
特点
- 同步写法,异步性能:用协程切换实现非阻塞,代码更简洁。
- 高并发低开销:协程轻量级,可同时处理数万连接。
- 需协程化扩展:依赖
Swoole\Runtime::enableCoroutine
和协程客户端。
示例代码
use Swoole\Runtime;
use Swoole\Coroutine;
// 启用协程 Hook(将阻塞函数转为协程)
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
$http = new Swoole\Http\Server('0.0.0.0', 9501);
$http->on('request', function ($req, $res) {
// 在协程上下文中运行
Coroutine::create(function () use ($res) {
// 协程化操作(如 MySQL 查询)
$result = Coroutine\System::sleep(1); // 非阻塞睡眠
$res->end("Coroutine Response");
});
});
$http->start();
三、对比总结
特性 | 同步模式 | 异步模式 | 协程模式 |
---|---|---|---|
代码复杂度 | 简单 | 复杂(回调嵌套) | 简单(类同步写法) |
性能 | 低(阻塞 Worker) | 高(非阻塞) | 极高(轻量级协程) |
适用场景 | 简单逻辑、低并发 | 高并发 I/O 密集型 | 高并发、复杂业务逻辑 |
资源占用 | 高(每请求独占进程/线程) | 中(事件循环) | 极低(协程复用) |
开发难度 | 低 | 高 | 中(需理解协程机制) |
四、关键配置差异
1. 同步模式
无需特殊配置,默认行为。
2. 异步模式
- 需使用
task
/finish
或异步客户端。 - 配置
worker_num
和task_worker_num
:$http->set([ 'worker_num' => 4, 'task_worker_num' => 8, ]);
3. 协程模式
- 必须开启协程 Hook:
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL); // 支持所有阻塞函数协程化
- 使用协程客户端(如
Swoole\Coroutine\MySQL
)。
五、性能测试对比
假设一个请求需要 1 秒的 I/O 等待:
- 同步模式:1 个 Worker 进程只能处理 1 QPS。
- 异步模式:1 个 Worker 可同时处理 N 个请求(取决于
reactor_num
)。 - 协程模式:1 个 Worker 可轻松处理 10k+ QPS(协程切换开销极小)。
六、选择建议
- 简单 API 服务 ➔ 同步模式(快速开发)。
- 高并发 + 旧代码迁移 ➔ 异步模式。
- 全新项目 + 高性能需求 ➔ 协程模式。