Swoole HTTP 服务中 同步、异步 和 协程 三种模式的对比

发布于:2025-03-23 ⋅ 阅读:(12) ⋅ 点赞:(0)

以下是 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_numtask_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 服务 ➔ 同步模式(快速开发)。
  • 高并发 + 旧代码迁移 ➔ 异步模式。
  • 全新项目 + 高性能需求 ➔ 协程模式。