zoukankan      html  css  js  c++  java
  • 浅析php curl_multi_*系列函数进行批量http请求

    何起:

      一系列 数量很大 数据不热 还希望被蜘蛛大量抓取的页面,在蜘蛛抓取高峰时,响应时间会被拉得很高。

      前人做了这样一个事儿:页面分3块,用3个内部接口提供,入口文件用curl_multi_*系列函数抓取3个内部接口的内容,拼成一个页面。

      怀疑这样做会有影响性能的可能。

      故学而分析之。

    看了php官方手册,总结批量调用过程如下:

      curl_multi_init — 返回一个新cURL批处理句柄,作为curl_init生成的单个curl句柄的容器

      curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄。

      curl_multi_exec — 运行当前 cURL 句柄的子连接,curl_multi_select()的值

        curl_multi_select — 等待所有cURL批处理中的活动连接

      curl_multi_getcontent — 如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流

      curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源

      curl_multi_close — 关闭一组cURL句柄

    摘一段php官网的示例代码:  

    <?php
    // 创建一对cURL资源
    $ch1 = curl_init();
    $ch2 = curl_init();
    
    // 设置URL和相应的选项
    curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");
    curl_setopt($ch1, CURLOPT_HEADER, 0);
    curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");
    curl_setopt($ch2, CURLOPT_HEADER, 0);
    
    // 创建批处理cURL句柄
    $mh = curl_multi_init();
    
    // 增加2个句柄
    curl_multi_add_handle($mh,$ch1);
    curl_multi_add_handle($mh,$ch2);
    
    $active = null;
    // 执行批处理句柄
    do {
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    
    while ($active && $mrc == CURLM_OK) {
        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }
    
    // 读取数据
    $content1 = curl_multi_getcontent($ch1);
    $content2 = curl_multi_getcontent($ch2);
    // 关闭全部句柄
    curl_multi_remove_handle($mh, $ch1);
    curl_multi_remove_handle($mh, $ch2);
    curl_multi_close($mh);
    
    ?>

    疑惑和思考:

      1.批量请求的原理

        php没有多线程,借助操作系统的多线程来实现(网上看到的)

      2.批量请求以操作系统的多线程机制为基础,理论上会大量消耗机器的cpu

        a.开发机上验证,大批量请求时,cpu调用确实会急剧升高

        b.对比 线上前端机的负载情况 和 页面响应时间拉长 的时间点,发现线上前端机负载并无明显升高(维持在0.3左右)

        c.网上看到有人在curl_multi_select()返回值不是-1的时候(表示有请求没有处理完成)usleep(100),休眠以避免不对读处理状态而造成的不必要cpu压力。

      notice:

        2中的a、b有所矛盾,暂未找到根本原因

        2中的c没有经过实践测试

    欢迎阅者批评指正

    笔者:一般的小帅

      

  • 相关阅读:
    C++课程的第一次实验
    First C++
    7-12 关于堆的判断
    大笨钟
    7-14 喊山
    L3-010 是否完全二叉搜索树 (30分)
    7-13 天梯地图
    7-10 排座位
    7-9 抢红包
    帅到没朋友
  • 原文地址:https://www.cnblogs.com/newbalanceteam/p/5292852.html
Copyright © 2011-2022 走看看