PHP中fork子进程时CURL返回异常计时结果的原因及修复方案咨询
PHP中fork子进程时CURL返回异常计时结果的原因及修复方案咨询
我正在尝试用PHP复刻ApacheBench(ab)压力测试工具,这样就能根据响应内容实现更定制化的控制逻辑。但在使用pcntl_fork()创建子进程发起请求时,得到的响应计时结果非常异常,和单进程非fork的情况差距很大。想请教各位大佬这是什么原因,以及该怎么修复才能得到fork执行时的真实请求耗时?
我的测试代码
<?php $start_time = microtime(true); function makeRequest(int $id) { $time = 0; $url = 'http://localhost:8080/'; $ch = curl_init(); curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); curl_setopt($ch, CURLOPT_FORBID_REUSE, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $info = curl_getinfo($ch); $time = $info['total_time']; curl_close($ch); echo "#$id. Response code: " . $code . ' in ' . $time * 1000 . ' ms' . PHP_EOL; } $repeat = 100; // 发起fork的请求 for ($i = 1; $i <= $repeat; ++$i) { $pid = pcntl_fork(); if (!$pid) { makeRequest($i); exit($i); } } while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo "\tChild $status completed" . PHP_EOL; } // 发起非fork的请求做对比 for ($i = 1; $i <= $repeat; ++$i) { makeRequest($i); } $finished = microtime(true); echo 'Finished all in ' . ($finished - $start_time) * 1000 . ' ms' . PHP_EOL;
测试环境
- 系统:MacOS
- PHP版本:8.4.4
- 执行命令:
php -f test_request.php
测试结果对比
非fork单进程请求(结果正常)
所有请求耗时都在1ms以内,输出如下:
#1. Response code: 200 in 0.737 ms #2. Response code: 200 in 0.586 ms #3. Response code: 200 in 0.516 ms #4. Response code: 200 in 0.575 ms #5. Response code: 200 in 0.557 ms ... #95. Response code: 200 in 0.351 ms #96. Response code: 200 in 0.348 ms #97. Response code: 200 in 0.389 ms #98. Response code: 200 in 0.394 ms #99. Response code: 200 in 0.345 ms #100. Response code: 200 in 0.323 ms
fork多进程请求(结果异常)
响应耗时随着请求数量增加而持续变长,部分请求甚至达到60ms以上,而且因为子进程并行输出,顺序也混乱了:
#1. Response code: 200 in 1.045 ms #2. Response code: 200 in 0.911 ms #3. Response code: 200 in 1.546 ms #4. Response code: 200 in 1.236 ms #5. Response code: 200 in 1.916 ms ... #93. Response code: 200 in 63.043 ms #92. Response code: 200 in 64.184 ms Child 95 completed Child 89 completed Child 88 completed #94. Response code: 200 in 65.008 ms Child 96 completed Child 97 completed #98. Response code: 200 in 60.779 ms #100. Response code: 200 in 54.383 ms
我的疑问
- 为什么fork子进程发起请求时,响应耗时会随着请求数增加而变长?这是真实的请求耗时还是计时逻辑有问题?
- 我的代码中有没有什么错误导致了这个异常结果?该怎么修改才能得到fork执行时的真实请求耗时?
内容来源于stack exchange
相关产品推荐
相关产品推荐

