记录将业务逻辑从 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 在空载或低负载情况下表现更优。选择哪种框架应根据具体业务需求和场景来决定。