业务逻辑从 Workerman 框架迁移到 Swoole 框架

分类: 兴趣杂文 标签: Workerman Swoole

记录将业务逻辑从 Workerman 框架迁移到 Swoole 框架过程中,进行的性能压测和相关经验。


📌 背景与动机

作者原本使用 Workerman 的 http-client 组件进行异步 HTTP 请求处理,但在实际业务中遇到与某些第三方 API 的兼容性问题,导致偶尔出现请求超时。为了解决这一问题,作者尝试使用 Swoole 的协程功能来替代原有的异步处理方式。


🧪 压测对比

1. 初始测试(Worker 数量为 20)

框架 并发 QPS CPU 占用
Workerman 4.02 16.0%
Swoole 11.15 91.3%

在相同的 Worker 数量下,Swoole 的性能明显优于 Workerman。

2. 增加 Workerman 的 Worker 数量至 200

框架 并发 QPS CPU 占用
Workerman 13.79 86.6%
Swoole 11.15 91.3%

通过增加 Worker 数量,Workerman 的性能有所提升,甚至超过了 Swoole。但作者注意到,大约一半的进程处于空闲状态,表明资源利用不均衡。

3. 空载测试(无业务延迟)

框架 并发 QPS CPU 占用
Workerman 7921 32.9%
Swoole 7601 32.8%

在无业务延迟的情况下,Workerman 的性能略优于 Swoole。


🧠 作者的见解

  • 在高负载场景下,Swoole 的协程机制表现出色,能够更好地处理并发请求。
  • Workerman 通过增加 Worker 数量也能达到类似的性能,但存在资源利用不均的问题。
  • Swoole 的协程切换虽然带来了一定的性能损耗,但在处理复杂业务逻辑时,优势明显。
  • 理论上,每个请求使用协程处理,并发 100 个请求,每个请求耗时 3 秒,应该可以在 4 秒内完成,但实际压测结果未达到预期。
  • Swoole 在处理跨协程调用、原子操作和资源竞争方面表现稳定,适合高并发场景。

🧾 压测代码示例

Swoole 示例

<?php
$server = new \Swoole\Http\Server('0.0.0.0', 9898);
$server->set([
    'worker_num' => swoole_cpu_num() * 2,
    'enable_coroutine' => true,
    'hook_flags' => SWOOLE_HOOK_ALL
]);
$server->on('request', function ($request, $response) {
    Swoole\Coroutine::create(function () use ($response) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://httpbin.org/delay/3");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        $result = curl_exec($ch);
        curl_close($ch);
        $response->end("hello world");
    });
});
$server->start();

Workerman 示例

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$http_worker = new Worker("http://0.0.0.0:9999");
$http_worker->count = 20;

$http_worker->onMessage = function (TcpConnection $connection, $request) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://httpbin.org/delay/3");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    $result = curl_exec($ch);
    curl_close($ch);
    $connection->send("hello world");
};
Worker::runAll();

📈 压测结果摘要

Workerman(Worker 数量为 20)

  • 请求数:121
  • QPS:4.02
  • CPU 占用:16.0%
  • 超时请求:43

Swoole(Worker 数量为 CPU 核心数 × 2)

  • 请求数:670
  • QPS:11.15
  • CPU 占用:91.3%
  • 超时请求:16

🔚 总结

这篇博客通过实际压测,展示了在处理异步 HTTP 请求时,Swoole 的协程机制在高负载场景下的优势,而 Workerman 在空载或低负载情况下表现更优。选择哪种框架应根据具体业务需求和场景来决定。