首页 > 编程语言 >php实现curl重试机制

php实现curl重试机制

时间:2022-12-29 17:33:03浏览次数:40  
标签:ch setopt 重试 curl php CURLOPT CONNECTTIMEOUT

前言,最近接手的项目中需要跨网络调用其他项目服务的API。由于网络中存在各种复杂的因素,导致curl请求偶尔出现下面错误。

Failed connect to www.xxx.com:80; Connection timed out

做了一下几点尝试:

  1. 抓包分析,也没有分析出个所以然。

  2. 以为是尝试连接的等待时间太小了,于是通过调整增大CURLOPT_CONNECTTIMEOUT参数,发现也无济于事。

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); //在尝试连接时等待的秒数

重试机制 由于之前的工作经历中,经常遇到各种偶发无法连接服务的情况如mysql等等,都是通过增加重试连接的方式解决的。

于是根据过往经验,干脆写了个curl请求重试机制,轻松解决了问题。特此分享一下:

    $ch = curl_init($url);
    //curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
    //curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-type:application/json;charset=utf-8"));
    curl_setopt($ch, CURLOPT_TIMEOUT, 1800);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); //在尝试连接时等待的秒数

    if (!empty($options)) {
        curl_setopt_array($ch, $options);
    }

    $data = curl_exec($ch);
    $curlErrno = curl_errno($ch);


    //curl增加重试机制
    $retryTimes=0;
    $maxRetryTimes=10;
    if($curlErrno)
    {
        for($retryTimes=0;$retryTimes<$maxRetryTimes;$retryTimes++)
        {
            $retryTimes++;

            $data = curl_exec($ch);
            $curlErrno = curl_errno($ch);
            if(!$curlErrno)
            {
                error_log("CURL重试{$retryTimes}次后成功".addslashes(json_encode(curl_getinfo($ch), JSON_UNESCAPED_UNICODE)));
                break;
            }
            sleep(1);
        }
    }

	//错误监控告警
    if ($curlErrno) {
        //curl请求异常,往上层抛出异常信息
        $errorMessage = 'CURL请求出错了!';
        $errorMessage .= '【地址】:' . $url . '。';
        $errorMessage .= '【方法】: GET。';
        $errorMessage .= '【参数】:' . addslashes(json_encode($postdata, JSON_UNESCAPED_UNICODE)) . '。';
        $errorMessage .= '【错误信息】:' . curl_error($ch) . "({$curlErrno}).";
        $errorMessage .= '【CURL_INFO】:' . addslashes(json_encode(curl_getinfo($ch), JSON_UNESCAPED_UNICODE)) . '。';

        #增加调用信息
        $backtrace = "";
        $backtraceList = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        foreach ($backtraceList as $v) {
            $fileName = $v['file'] ?? '';
            $lineNo = $v['line'] ?? 0;
            $className = $v['class'] ?? '';
            $functionName = $v['function'] ?? '';
            $backtrace .= "{$fileName} - {$lineNo} - {$className}::{$functionName}()" . '。';
        }
        $errorMessage .= '【调用】:' . $backtrace;
        $errorMessage .= '【重试次数】:' . $retryTimes;
        $errorMessage .= '【处理服务器】:' . gethostname();


        $errorMessage = str_replace(array("\r\n", "\r", "\n", "   "), '', $errorMessage);
	
	  //告警通知
        qywx_robot_error_notice($errorMessage);
        unset($errorMessage, $backtrace, $backtraceList);

        //throw new \Exception(curl_error($ch),$errorNo);
        //return false;
    }

    curl_close($ch);

    return $data;

标签:ch,setopt,重试,curl,php,CURLOPT,CONNECTTIMEOUT
From: https://blog.51cto.com/phpme/5978629

相关文章

  • PHP 数组
    数组能够在单独的变量名中存储一个或多个值。实例数组在单个变量中存储多个值:<?php$cars=array("porsche","BMW","Volvo");echo"Ilike".$cars[0].",".$c......
  • PHP 多维数组
    在本教程之前的章节中,我们已经知道数组是一种数/值对的简单列表。不过,有时您希望用一个以上的键存储值。可以用多维数组进行存储。PHP-多维数组多维数组指的是包......
  • PHP for 循环
    PHPfor循环执行代码块指定的次数。PHPfor循环如果您已经提前确定脚本运行的次数,可以使用for循环。语法for(initcounter;testcounter;incrementcounter)......
  • grpc php plugin 源码编译(windows)grpc_php_plugin.exe
    1:下载cmake国内下载地址 https://cmake.org/files/v3.25/2:  chocoinstallnasm 3:git4:virtualstudio2022(需要选择cmakec++支持以及选择windows11sdk......
  • php 循环查询接口
    do{$notify_time=time();$last_notify_time=time();$resultPartnerNotify=getHttpResponsePOST($notifyU......
  • php 查询手机号归属接口
    <?php//手机号查询归属地functionmobileAscription($mobile){$url="https://chong.qq.com/tws/mobileqqprequery/GetMobileProductInfo?loginstate=1......
  • PhpStorm 2022 for mac(PHP集成开发工具)v2022.3.1中文版
    mac版PhpStorm2022 v2022.3.1中文版更新了,PhpStorm2022formac(PHP集成开发工具)v2022.3.1中文版分享给大家,PhpStorm是一个实际“获取”你的代码的PHPIDE。它支持PHP......
  • PHP性能优化
    1.避免在循环时做一些运算操作以及数据库查询操作//优化前,每循环1次,都要执行1次count()函数$arr=[2,3,4,52,233,55,677];for($i=0;$i<count($arr);$i++){ //dos......
  • 编译php7.4和php8.0编译安装,pkg-config详情
    2022年12月21日15:49:28官网连接:https://www.php.net/manual/zh/migration74.other-changes.php#migration74.other-changes.pkg-config一些扩展已经迁移到只使用pkg-co......
  • How to install VirtualBox 6.x with phpVirtualbox web interface on Debian 11 bull
    HowtoinstallVirtualBox6.xwithphpVirtualboxwebinterfaceonDebian11bullseye/openmediavault6ThenewOpenMediaVault6usesDebian11asthebasesys......