curl+exec实现异步无等待请求

一、背景

  前天中午同事问我一个问题,他有一个需求就是在某个页面中需要调用一下第三方的一个地址,目的是第三方会根据你发的请求做一个统计。

  问题分析:

  1:对终端用户来说这个接口调用完全没有意义

  2:如果接口响应(建立连接时间+响应时间)过慢,那么就会影响用户体验。

  理想状态:

  在页面的某个点捅一下这个接口完事,瞬间就继续往下走。

二、解决方案


1:当时我首先想到的解决方案是用curl的异步,设置建立连接的时间稍微长一点,但是响应时间设置为毫秒级。

代码如下:


<?php
$nodes = array('http://consis.learn.com/curl/c.php', 'http://consis.learn.com/curl/d.php'); 
    $node_count = count($nodes); 
    
    $curl_arr = array(); 
    $master = curl_multi_init(); 
    
    for($i = 0; $i < $node_count; $i++) { 
        $url =$nodes[$i]; 
        $curl_arr[$i] = curl_init($url); 
        curl_setopt($curl_arr[$i], CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($curl_arr[$i], CURLOPT_CONNECTTIMEOUT, 1); //建立连接等待时间
        curl_setopt($curl_arr[$i], CURLOPT_TIMEOUT_MS, 10);//响应超时时间
        curl_multi_add_handle($master, $curl_arr[$i]); 
    } 
    do { 
        curl_multi_exec($master,$running); 
    } while($running > 0); 
    
    echo "results: "; 
    
    for($i = 0; $i < $node_count; $i++) { 
        $results = curl_multi_getcontent  ( $curl_arr[$i]  );  
        echo( $i . "\n" . $results . "\n"); 
    } 
    
    echo 'done';

其中c.php和d.php的代码如下:

c.php:

<?php
 error_log(date("Y-m-d H:i:s") . "\there1\n", 3, "/tmp/a.log");
 sleep(5);
 error_log(date("Y-m-d H:i:s") . "\there2\n", 3, "/tmp/a.log");
 echo 'test a b c';

d.php:

<?php
echo "this is c d e f g";

这样做基本可以实现效果,但是还是不完美,因为虽然这样虽然基本可以忽略对方的响应时间,但是避免不了建立连接花费的时间,如果和对方距离过长,中间网络问题都有可能达到最大值,而且这个最大值也不能设置太大,还会造成数据丢失问题问题:比如你设置1秒,而如果1秒还未建立连接成功,那么其实对方是收不到这次请求的。

2:第二种方案很完美的解决了这个问题,是我同事自己想出来的。

用的是curl+exec

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值