CURL解析超时的解决方案

背景:项目中需要在抓取纷享销客CRM图片上传到OSS,调用OssClient.php时,容易发生解析超时(多重试几次就ok)。

错误提示:

[2019-04-08 19:41:01] lumen.DEBUG: 出错文件:/home/zrj/www/admin/yundou-admin/vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php
[2019-04-08 19:41:01] lumen.DEBUG: 出错编码:0
[2019-04-08 19:41:01] lumen.DEBUG: 出错行号:2187
[2019-04-08 19:41:01] lumen.DEBUG: 出错信息:RequestCoreException: cURL resource: Resource id #371; cURL error: Resolving timed out after 10521 milliseconds (28) 

Resolving timed out after 10521 milliseconds (28)
解析超时

源码分析:

try {
            $ossClient = new OssClient(self::$accessKeyId, self::$accessKeySecret, self::$endpoint);
            $ossClient->uploadFile(self::$bucket, $ossFileName, $localhostFileName);//上传文件
            $ossClient->putBucketAcl(self::$bucket, OssClient::OSS_ACL_TYPE_PUBLIC_READ);
        } catch (OssException $e) {
            self::debugException($e);
            throw new \Exception("上传oss失败:" . $e->getMessage(), $e->getCode());
        }

1.实例化OssClient客户端后,调用uploadFile方法。
2.uploadFile调用了auth,验证并且执行请求,按照OSS Api协议,执行操作。

    /**
     * 上传本地文件
     *
     * @param string $bucket bucket名称
     * @param string $object object名称
     * @param string $file 本地文件路径
     * @param array $options
     * @return null
     * @throws OssException
     */
    public function uploadFile($bucket, $object, $file, $options = NULL)
    {
        ......
        $response = $this->auth($options);
        $result = new PutSetDeleteResult($response);
        return $result->getData();
    }

3.auth中调用RequestCore类创建请求

    /**
     * 验证并且执行请求,按照OSS Api协议,执行操作
     *
     * @param array $options
     * @return ResponseCore
     * @throws OssException
     * @throws RequestCore_Exception
     */
    private function auth($options)
    {
            ......
        //创建请求
        $request = new RequestCore($this->requestUrl, $this->requestProxy);
        $request->set_useragent($this->generateUserAgent());
                ......
                try {
            $request->send_request();
        } catch (RequestCore_Exception $e) {
            throw(new OssException(‘RequestCoreException: ‘ . $e->getMessage()));
        }
    }

4.OSS\Http\RequestCore类中send_request方法通过CURL发送请求(调用了prep_request准备请求方法)

 /**
     * Sends the request, calling necessary utility functions to update built-in properties.
     *
     * @param boolean $parse (Optional) Whether to parse the response with ResponseCore or not.
     * @return string The resulting unparsed data from the request.
     */
    public function send_request($parse = false)
    {
        set_time_limit(0);

        $curl_handle = $this->prep_request();
        $this->response = curl_exec($curl_handle);

        if ($this->response === false) {
            throw new RequestCore_Exception(‘cURL resource: ‘ . (string)$curl_handle . ‘; cURL error: ‘ . curl_error($curl_handle) . ‘ (‘ . curl_errno($curl_handle) . ‘)‘);
        }

        $parsed_response = $this->process_response($curl_handle, $this->response);

        curl_close($curl_handle);

        if ($parse) {
            return $parsed_response;
        }

        return $this->response;
    }

5.最终可以推导出问题出在RequestCore中的CURL。

解决方案:
curl有一个CURLOPT_IPRESOLVE选项,作用是指定使用那种IP协议(IPV4/IPV6)。

CURLOPT_IPRESOLVE - specify which IP protocol version to use

选项:
CURL_IPRESOLVE_WHATEVER

Default, resolves addresses to all IP versions that your system allows.

CURL_IPRESOLVE_V4

Resolve to IPv4 addresses.

CURL_IPRESOLVE_V6

Resolve to IPv6 addresses.

这里要注意:默认值(curl没有主动设置CURLOPT_IPRESOLVE选项时,则系统会使用默认值)。

Default, resolves addresses to all IP versions that your system allows.

含义为:默认使用服务器系统允许的所有IP版本来解析地址。
而服务器系统可能存在同时支持IPV4/IPV6,CURL会挨个去试。当本地网络不支持其中任何一种IP版本协议时,会出现超时。

所以,最终的解决方案为显式指定CURL的CURLOPT_IPRESOLVE选项。

curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

参考官方CURLOPT_IPRESOLVE

原文地址:https://blog.51cto.com/phpme/2375587

时间: 2024-10-10 17:33:45

CURL解析超时的解决方案的相关文章

Android Studio安装后Fetching android sdk component information超时的解决方案

问题描述: Android Studio 是一个全新的 Android 开发环境,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试. Android Studio安装完成后,如果直接启动,Android Studio会去获取 android sdk 组件信息,这个过程相当慢,还经常加载失败,导致Android Studio启动不起开.解决办法就是不去获取android sdk 组件信息. 解决方法:

curl的超时时间设置

curl的超时时间设置 使用curl时,有两个超时时间:一个是连接超时时间,另一个是数据传输的最大允许时间. 连接超时时间: --connect-timeout 例: curl --connect-timeout 1 "http://localhost/index.html" 出错提示形如: curl: (28) connect() timed out! 不能连接提示如: curl:(7) couldn't connect to host 数据传输的最大允许时间用: -m 例: cur

php使用curl设置超时的重要性

原文:php使用curl设置超时的重要性 原文:http://phpquan.com/lamp/php/php-curl-timeout/ 网站登录不了,原因是没有可用的 PHP 子进程来响应新的请求了.这可能是是由于PHP-curl  没有设置超时时间引起的. 这段时间用PHP写了个爬虫程序,但是经常执行了一段时间后程序就卡住了.程序是用的curl方式进行抓取,后来设置了 CURLOPT_TIMEOUT 参数就没有出现这个问题了平常如果测试curl都直接设置了url就直接执行了.curl功能还

ASP.NET Core MVC请求超时设置解决方案

设置请求超时解决方案 当进行数据导入时,若导入数据比较大时此时在ASP.NET Core MVC会出现502 bad gateway请求超时情况(目前对于版本1.1有效,2.0未知),此时我们需要在项目web.config配置文件中进行如下设置即可: <?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <handlers>

MySQL 连接中 IP 或端口错误导致连接超时的解决方案

在 Visual Studio 中调用 mysql_real_connect() 函数连接 MySQL 过程中,当仅有连接 IP 错误时,会存在大概 20 秒的连接超时,最后连接失败:当有连接端口错误时,会存在大概 60 秒连接超时,最后连接失败. 通过在 mysql_real_connect() 前配置以下函数: mysql_options(handle, MYSQL_OPT_CONNECT_TIMEOUT, timeOut) 但并不能成功在超时时间之后,结束连接请求. 这里提供一种线程解决方

curl解析公网ip

curl icanhazip.com curl ifconfig.me

dubbo服务调用超时问题解决方案

dubbo在调用服务不成功时,默认是会重试两次的.这样在服务端的处理时间超过了设定的超时时间时,就会有重复请求,比如在发邮件时,可能就会发出多份重复邮件,执行注册请求时,就会插入多条重复的注册数据,那么怎么解决超时问题呢?如下 1.对于核心的服务中心,去除dubbo超时重试机制,并重新评估设置超时时间. 2.业务处理代码必须放在服务端,客户端只做参数验证和服务调用,不涉及业务流程处理 当然Dubbo的重试机制其实是非常好的QOS保证,它的路由机制,是会帮你把超时的请求路由到其他机器上,而不是本机

ASP.NET- 执行SQL超时的解决方案

在我们编写程序的时候,有时候要进行复杂的查询时,就会出现执行sql时间过长,引起页面执行不了并提示执行脚本超时,这就是我们遇到超时异常. 超时异常分两种情况:一种,是连接超时:一种,是执行超时.前者,通过SqlConnection.ConnectionTimeOut进行设置.后者,通过SqlCommand.CommandTimeOut进行设置. SqlConnection.ConnectionTimeout获取在尝试建立连接时终止尝试并生成错误之前所等待的时间.等待连接打开的时间(以秒为单位).

使用 Microsoft.ApplicationBlocks.Data SqlHelper 查询超时以及解决方案

 提示: 后面附有文件,不喜欢看吐槽的,直接到文章结尾下载 摘要:Data Access Application Block 是一个 .NET 组件,包含优化的数据访问代码,可以帮助用户调用存储过程以及向 SQL Server 数据库发出 SQL 文本命令.它返回 SqlDataReader.DataSet 和 XmlReader 对象.您可以在自己的 .NET 应用程序中将其作为构造块来使用,以减少需要创建.测试和维护的自定义代码的数量.您可以下载完整的 C# 和 Visual Basic .