我正在编写一个界面,我必须在其中启动4个http请求以获取一些信息。
我以两种方式实现了界面:
我用jmeter对2个版本进行了基准测试。结果表明,当jmeter中只有1个线程发出请求时,多卷曲比顺序file_get_contents要好得多,但是当100个线程时更糟糕。
问题是:哪个会导致多卷曲的糟糕表现?
我的多卷曲代码如下:
$_POST
答案 0 :(得分:3)
curl_multi_select
失败,你应该睡大约2500微秒
实际上,它有时会在每次执行时彻底失败
没有睡眠,您的CPU资源会被许多while (true) { }
循环占用。CURLM_CALL_MULTI_PERFORM
不再出现。所以,以下代码
$running = null;
$mrc = null;
do
{
$mrc = curl_multi_exec( $master , $running );
}
while ( $mrc == CURLM_CALL_MULTI_PERFORM );
while ( $running && $mrc == CURLM_OK )
{
if (curl_multi_select( $master ) != - 1)
{
do
{
$mrc = curl_multi_exec( $master , $running );
}
while ( $mrc == CURLM_CALL_MULTI_PERFORM );
}
}
应该是
curl_multi_exec($master, $running);
do
{
if (curl_multi_select($master, 99) === -1)
{
usleep(2500);
continue;
}
curl_multi_exec($master, $running);
} while ($running);
只有在您想要执行类似......
之类的操作时,才应调整curl_multi_select
的超时值
curl_multi_exec($master, $running);
do
{
if (curl_multi_select($master, $TIMEOUT) === -1)
{
usleep(2500);
continue;
}
curl_multi_exec($master, $running);
while ($info = curl_multi_info_read($master))
{
/* Do something with $info */
}
} while ($running);
否则,该值应该非常大。
(但是,PHP_INT_MAX
太大; libcurl将其视为无效值。)
我使用我的并行cURL执行程序库进行了测试:mpyw/co
(准备工作for
不合适,应该是by
,抱歉我的英语不好xD)
<?php
require 'vendor/autoload.php';
use mpyw\Co\Co;
function four_sequencial_requests_for_one_hundread_people()
{
for ($i = 0; $i < 100; ++$i) {
$tasks[] = function () use ($i) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'example.com',
CURLOPT_FORBID_REUSE => true,
CURLOPT_RETURNTRANSFER => true,
]);
for ($j = 0; $j < 4; ++$j) {
yield $ch;
}
};
}
$start = microtime(true);
yield $tasks;
$end = microtime(true);
printf("Time of %s: %.2f sec\n", __FUNCTION__, $end - $start);
}
function requests_for_four_hundreds_people()
{
for ($i = 0; $i < 400; ++$i) {
$tasks[] = function () use ($i) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'example.com',
CURLOPT_FORBID_REUSE => true,
CURLOPT_RETURNTRANSFER => true,
]);
yield $ch;
};
}
$start = microtime(true);
yield $tasks;
$end = microtime(true);
printf("Time of %s: %.2f sec\n", __FUNCTION__, $end - $start);
}
Co::wait(four_sequencial_requests_for_one_hundread_people(), [
'concurrency' => 0, // Zero means unlimited
]);
Co::wait(requests_for_four_hundreds_people(), [
'concurrency' => 0, // Zero means unlimited
]);
我尝试了五次以获得以下结果:
我也尝试了相反的顺序(第三个请求被踢了xD):
这些结果表示过多的并发TCP连接实际上会降低吞吐量。
如果要针对少数和多个并发请求进行优化,以下脏解决方案可能会对您有所帮助。
apcu_add
/ apcu_fetch
/ apcu_delete
分享请求者的数量。 CURLMOPT_PIPELINING
会帮助你。 此选项将同一目标的所有HTTP / 1.1连接捆绑到一个TCP连接中。
curl_multi_setopt($master, CURLMOPT_PIPELINING, 1);