我不知道如何检查多路复用的操作,以及是否在执行期间。
我向 curl_multi_exec() 添加了4 个 curl_init ( )描述符,它们执行对一个域的请求。在CURLOPT_VERBOSE日志中,在第一个描述符的每个后续中,我看到以下行:
* Found bundle for host yandex.ru: 0x55adc86744f0 [serially]
更多细节。
例子:
// создаем дескриптор cURL
$ch1 = curl_init();
// устанавливаем опции
curl_setopt($ch1, CURLOPT_URL, "https://yandex.ru");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_FILE, $curl1_exec);
curl_setopt($ch1, CURLOPT_STDERR, $curl1_log);
curl_setopt($ch1, CURLOPT_VERBOSE, 1);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch1, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// создаем новый дескриптор копированием существующего
$ch2 = curl_copy_handle($ch1);
// устанавливаем новые опции
curl_setopt($ch2, CURLOPT_URL, "https://yandex.ru/all");
curl_setopt($ch2, CURLOPT_FILE, $curl2_exec);
curl_setopt($ch2, CURLOPT_STDERR, $curl2_log);
// создаем новый дескриптор копированием существующего
$ch3 = curl_copy_handle($ch1);
// устанавливаем новые опции
curl_setopt($ch3, CURLOPT_URL, "https://yandex.ru/news/");
curl_setopt($ch3, CURLOPT_FILE, $curl3_exec);
curl_setopt($ch3, CURLOPT_STDERR, $curl3_log);
// создаем новый дескриптор копированием существующего
$ch4 = curl_copy_handle($ch1);
// устанавливаем новые опции
curl_setopt($ch4, CURLOPT_URL, "https://yandex.ru/images/?from=tabbar");
curl_setopt($ch4, CURLOPT_FILE, $curl4_exec);
curl_setopt($ch4, CURLOPT_STDERR, $curl4_log);
//создаем набор дескрипторов cURL
$mh = curl_multi_init();
//добавляем дескрипторы
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
curl_multi_add_handle($mh, $ch3);
curl_multi_add_handle($mh, $ch4);
//добавляем попытку использовать мультиплексирование, если это возможно
curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
//запускаем множественный обработчик
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
// Ждем какое-то время для оживления активности
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
//закрываем дескрипторы
curl_multi_close($mh);
连接信息。
第一的:
* Rebuilt URL to: https://yandex.ru/
* Hostname 'yandex.ru' was found in DNS cache
* Trying 77.88.55.60...
* TCP_NODELAY set
* Connected to yandex.ru (77.88.55.60) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=yandex.ru; O=Yandex LLC; OU=ITO; L=Moscow; ST=Russia; C=RU
* start date: Sep 5 11:12:34 2019 GMT
* expire date: Sep 4 11:12:34 2020 GMT
* subjectAltName: host "yandex.ru" matched cert's "yandex.ru"
* issuer: C=RU; O=Yandex LLC; OU=Yandex Certification Authority; CN=Yandex CA
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x556999495740)
> GET / HTTP/2
Host: yandex.ru
Accept: */*
第二:
* Found bundle for host yandex.ru: 0x5569994ce320 [serially]
* Server doesn't support multi-use (yet)
* Hostname 'yandex.ru' was found in DNS cache
* Trying 77.88.55.60...
* TCP_NODELAY set
* Connected to yandex.ru (77.88.55.60) port 443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=yandex.ru; O=Yandex LLC; OU=ITO; L=Moscow; ST=Russia; C=RU
* start date: Sep 5 11:12:34 2019 GMT
* expire date: Sep 4 11:12:34 2020 GMT
* subjectAltName: host "yandex.ru" matched cert's "yandex.ru"
* issuer: C=RU; O=Yandex LLC; OU=Yandex Certification Authority; CN=Yandex CA
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55699949ea40)
> GET /all HTTP/2
Host: yandex.ru
Accept: */*
在您的示例中,多路复用不起作用,
Connected to ... (#1)第二个日志中至少有一行表明了这一点(到该主机的连接号在括号中表示)。而且,TLS 握手再次发生的事实。要进行测试以查看多路复用的实际效果,请使用选项将与服务器的连接数限制为 1
CURLMOPT_MAX_HOST_CONNECTIONS。以下是多路复用工作时日志的外观:
日志显示,当连接忙于第一个请求时,第二个和第三个请求无法启动。此外,在解析主机名并至少建立一个连接之前,无法开始多路复用。连接建立后,curl发送第一个请求,由于允许多路复用,它在同一个连接中发送队列中剩余的2个请求。
而当 curl 对连接数没有限制并且还没有活动连接时,它更容易一次打开多个并行连接并并行发送请求而无需多路复用。