curl_multi_exec与curl_exec

curl_multi_exec与curl_exec

/*
CURLOPT_CONNECTTIMEOUT用来告诉PHP脚本在成功连接服务器前等待多久(连接成功之后就会开始缓冲输出),这个参数是为了应对目标服务器的过载,下线,或者崩溃等可能状况;

CURLOPT_TIMEOUT 用来告诉成功PHP脚本,从服务器接收缓冲完成前需要等待多长时间。如果目标是个巨大的文件,生成内容速度过慢或者链路速度过慢,这个参数就会很有用。

CURL 是常用的访问HTTP协议接口的lib库,性能高,还有一些并发支持的功能等。  
curl_setopt($ch, opt) 可以设置一些超时的设置,主要包括:    
① (重要) CURLOPT_TIMEOUT 设置cURL允许执行的最长秒数。      
② (重要) CURLOPT_TIMEOUT_MS 设置cURL允许执行的最长毫秒数。    

③  CURLOPT_CONNECTTIMEOUT 在发起连接前等待的时间,如果设置为0,则无限等待。 
④ CURLOPT_CONNECTTIMEOUT_MS 尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。  (curl_setopt($conn, CURLOPT_NOSIGNAL,1);)  
⑤ CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,0不缓存,-1永久缓存,默认120s
*/

$urls = array(
    "http://192.168.33.10:815/swoole/swoole_call/sleep.php",
    'sleep' => "http://192.168.33.10:815/swoole/swoole_call/sleep.php",
    'test' => "http://www.data13.com",
);


$timeBegin=explode('.',microtime(true));
$timeBeginFloat=microtime(true);
echo 'curl begin '.date('Y-m-d H:i:s',$timeBegin[0]).'.'.$timeBegin[1];

$curlMulti=curlMulti($urls);

$timeEnd=explode('.',microtime(true));
echo ' curl end '.date('Y-m-d H:i:s',$timeEnd[0]).'.'.$timeEnd[1].',total exec time '.bcsub(microtime(true),$timeBeginFloat,4);

var_dump($curlMulti);
echo '<hr>';

$timeBegin=explode('.',microtime(true));
$timeBeginFloat=microtime(true);
echo 'curl begin '.date('Y-m-d H:i:s',$timeBegin[0]).'.'.$timeBegin[1];

$curlOneRst=[];
foreach($urls as $k=>$v){
$curlOneRst[]=curlOne($v);
}

$timeEnd=explode('.',microtime(true));
echo ' curl end '.date('Y-m-d H:i:s',$timeEnd[0]).'.'.$timeEnd[1].',total exec time '.bcsub(microtime(true),$timeBeginFloat,4);

var_dump($curlOneRst);   


function curlMulti($urls){
    $ch = array();
    $res = array();
    $conn = array();

    // 创建批处理cURL句柄
    $mh = curl_multi_init();

    foreach ($urls as $i => $url) {
        $conn[$i]=curlInit($url);
        // 增加句柄
        curl_multi_add_handle($mh, $conn[$i]);
    }

    $active = null;
    do {
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active && $mrc == CURLM_OK) {
        if (($multiSelect=curl_multi_select($mh)) != -1) {
            usleep(100);
        }
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);

        /*
        if (($multiSelect=curl_multi_select($mh)) != -1) {
            do {
                $mrc = curl_multi_exec($mh, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
        */

    }

    foreach ($urls as $i => $url) {
        //获取请求头信息
        //$heards = curl_getinfo($conn[$i]);
        //var_dump($heards);

        //获取输出的文本流
        $res[$i] = curl_multi_getcontent($conn[$i]);
        // 移除curl批处理句柄资源中的某个句柄资源
        curl_multi_remove_handle($mh, $conn[$i]);

        //关闭cURL会话
        curl_close($conn[$i]);
    }
    //关闭全部句柄
    curl_multi_close($mh);
    return $res;
}


function curlOne($url){
    $conn=curlInit($url);
     $response = curl_exec($conn);
    if ($response === FALSE) {
      $error = curl_error($conn) . ' [' . curl_errno($conn) . ']';
    }
    $headers = curl_getinfo($conn); //CURLINFO_HEADER_SIZE
    //关闭cURL会话
    curl_close($conn);
    return $response;
}

function curlInit($url){
    // 创建cURL资源
    $conn = curl_init();
    // 设置URL和相应的选项
    curl_setopt($conn, CURLOPT_URL, $url);
    curl_setopt($conn, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($conn, CURLOPT_DNS_CACHE_TIMEOUT,0);

    curl_setopt($conn, CURLOPT_TIMEOUT,5);
    curl_setopt($conn, CURLOPT_NOSIGNAL,1);
    curl_setopt($conn, CURLOPT_CONNECTTIMEOUT_MS,300);
    return $conn;
}

sleep.php

sleep(1);

$rst=['status'=>200,'msg'=>'ok'];
echo json_encode($rst);

这里写图片描述

参考

understanding php curl_multi_exec
https://stackoverflow.com/questions/15559157/understanding-php-curl-multi-exec

Doing curl_multi_exec the right way
http://www.adrianworlddesign.com/Knowledge-Base/php/Download-content-with-cURL/Doing-curlmultiexec-the-right-way

PHP and curl_multi_exec
http://technosophos.com/2012/10/26/php-and-curlmultiexec.html

php curl_multi_exec 官网例子里面为啥有两次 do while
https://segmentfault.com/q/1010000005159193

curl_multi_select解决curl_multi网页假死问题
https://www.cnblogs.com/chunguang/p/5895174.html

php curl 批量请求
https://blog.csdn.net/u013372487/article/details/51956996

php中curl同时发送多个请求curl_multi函数集的用法
https://blog.csdn.net/xueling022/article/details/51907990

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
curlcurl_multi都是用于进行网络请求的工具。 curl是一个命令行工具,可以通过发送HTTP请求来获取网页内容或发送其他类型的网络请求。它是单线程的,在发送一个请求时会阻塞程序的执行直到请求完成并返回结果。这意味着如果要进行高并发的请求,需要启动多个curl进程来同时发送多个请求,但会造成系统资源的浪费。 而curl_multi是一个C语言库,可以实现多个网络请求的并发执行。它通过将多个curl实例放入一个集合中,并使用事件循环来处理多个请求的同时执行。这样,在发送一个请求时,程序不会阻塞,而是可以继续执行其他任务,提高了并发处理能力。当所有的请求都完成时,可以一次性获取所有的结果。这种方式减少了系统资源的浪费,提高了程序的效率。 使用curl_multi进行高并发需要注意以下几点: 1. 创建curl_multi实例,并向其中添加需要执行的curl请求。 2. 使用curl_multi_exec函数来开始执行多个请求。 3. 使用curl_multi_select函数等待请求完成。 4. 使用curl_multi_getcontent函数获取每个请求的结果。 需要注意的是,高并发的网络请求对服务器压力较大,也容易出现网络超时等问题,因此需要合理控制并发请求数量,使用适当的技术手段,如连接池、负载均衡等,来保证系统的稳定性和性能。 总之,curlcurl_multi都可以用于高并发的网络请求,但curl_multi具有更好的并发性能和资源利用率,适合在程序中进行大量请求的同时执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值