RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1028921
Accepted
Алексей
Алексей
Asked:2020-09-28 18:44:58 +0000 UTC2020-09-28 18:44:58 +0000 UTC 2020-09-28 18:44:58 +0000 UTC

在 PHP 中与 cURL 进行多路复用的工作示例

  • 772

我不知道如何检查多路复用的操作,以及是否在执行期间。

我向 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: */*
php
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    zed
    2020-09-28T20:39:30Z2020-09-28T20:39:30Z

    在您的示例中,多路复用不起作用,Connected to ... (#1)第二个日志中至少有一行表明了这一点(到该主机的连接号在括号中表示)。而且,TLS 握手再次发生的事实。

    要进行测试以查看多路复用的实际效果,请使用选项将与服务器的连接数限制为 1 CURLMOPT_MAX_HOST_CONNECTIONS。

    以下是多路复用工作时日志的外观:

    * Found bundle for host yandex.ru: 0x1d477a8 [serially]
    * Server doesn't support multiplex (yet)
    * Connection #0 is still name resolving, can't reuse
    * No more connections allowed to host yandex.ru: 1
    * No connections available.
    * Found bundle for host yandex.ru: 0x1d477a8 [serially]
    * Server doesn't support multiplex (yet)
    * Connection #0 is still name resolving, can't reuse
    * No more connections allowed to host yandex.ru: 1
    * No connections available.
    *   Trying 5.255.255.70:443...
    * TCP_NODELAY set
    * Connected to yandex.ru (5.255.255.70) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: G:/dev/msys32/mingw32/ssl/certs/ca-bundle.crt
      CApath: none
    * 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 0x1d37770)
    > GET /all HTTP/2
    Host: yandex.ru
    Accept: */*
    
    * Found bundle for host yandex.ru: 0x1d477a8 [can multiplex]
    * Multiplexed connection found!
    * Found connection 0, with 1 requests on it
    * Re-using existing connection! (#0) with host yandex.ru
    * Transfer was pending, now try another
    * Using Stream ID: 3 (easy handle 0x1d3c898)
    > GET /news/ HTTP/2
    Host: yandex.ru
    Accept: */*
    
    * Found bundle for host yandex.ru: 0x1d477a8 [can multiplex]
    * Multiplexed connection found!
    * Found connection 0, with 2 requests on it
    * Re-using existing connection! (#0) with host yandex.ru
    * Transfer was pending, now try another
    * Using Stream ID: 5 (easy handle 0x1d419c0)
    > GET /images/?from=tabbar HTTP/2
    Host: yandex.ru
    Accept: */*
    
    * old SSL session ID is stale, removing
    * Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
    < HTTP/2 302
    < content-length: 0
    < content-type: text/plain
    < date: Sat, 28 Sep 2019 12:14:11 GMT
    < location: https://yandex.by/images/?from=tabbar&rdrnd=81726&redircnt=156967285
    1.1
    < x-yandex-items-count: 30
    < x-content-type-options: nosniff
    < set-cookie: yandexuid=5793565301569672851; path=/; domain=.yandex.ru; expires=
    Thu, 31-Dec-2037 20:59:59 GMT
    < set-cookie: i=qNCxtom97cEsA8UD8N95FpWH+3kBHHWfa3Qknvqzjw2kyyvxbSgXMBH/WFdA29/z
    /yopQn/FrZ80Rsfj43BeU1ZSzyk=; Expires=Tue, 25-Sep-2029 12:14:11 GMT; Domain=.yan
    dex.ru; Path=/; Secure; HttpOnly
    <
    < HTTP/2 200
    < content-length: 72727
    < content-security-policy: style-src 'unsafe-inline' https://yastatic.net;connec
    t-src https://yandex.ru https://mc.admetrica.ru https://mc.yandex.ru;default-src
     'none';font-src https://yastatic.net;script-src 'unsafe-inline' https://yastati
    c.net https://mc.yandex.ru;report-uri https://csp.yandex.net/csp?project=morda&f
    rom=morda.big.ru&showid=1569672851.79748.122006.776086&h=sas2-0701-sas-portal-mo
    rda-17154&csp=new&date=20190928&yandexuid=1030803431569672851;frame-src https://
    mc.yandex.ru;img-src https://yastatic.net https://mc.yandex.ru data: https://yan
    dex.ru https://mc.admetrica.ru 'self'
    < date: Sat, 28 Sep 2019 12:14:11 GMT
    < x-content-type-options: nosniff
    < set-cookie: yandexuid=1030803431569672851; Expires=Tue, 25-Sep-2029 12:14:11 G
    MT; Domain=.yandex.ru; Path=/
    < set-cookie: i=eOTzJeGXmxCjNGdYdiFXilW2ovcfoCamtMYnr75DHJTod24FA3t7/XQ0oPq7ocbb
    7Cjf1l2qtypRQaj44c7lTlHoJKc=; Expires=Tue, 25-Sep-2029 12:14:11 GMT; Domain=.yan
    dex.ru; Path=/; Secure; HttpOnly
    < x-frame-options: DENY
    < expires: Sat, 28 Sep 2019 12:14:12 GMT
    < p3p: policyref="/w3c/p3p.xml", CP="NON DSP ADM DEV PSD IVDo OUR IND STP PHY PR
    E NAV UNI"
    < last-modified: Sat, 28 Sep 2019 12:14:12 GMT
    < cache-control: no-cache,no-store,max-age=0,must-revalidate
    < content-type: text/html; charset=UTF-8
    <
    

    日志显示,当连接忙于第一个请求时,第二个和第三个请求无法启动。此外,在解析主机名并至少建立一个连接之前,无法开始多路复用。连接建立后,curl发送第一个请求,由于允许多路复用,它在同一个连接中发送队列中剩余的2个请求。

    而当 curl 对连接数没有限制并且还没有活动连接时,它更容易一次打开多个并行连接并并行发送请求而无需多路复用。

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5