前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CURL的超时与重试

CURL的超时与重试

作者头像
用户2825413
发布2020-02-11 14:52:25
10.7K0
发布2020-02-11 14:52:25
举报

curl 的功能非常强大, 参数也很繁多, 我们不仅常用于命令行, 在php中也有类似 curl 拓展的实现, 并且也对 libcurl 库提供了非常好的支持.

curl 项目: https://github.com/curl/curl

curl 关于时间控制和重试的参数

代码语言:javascript
复制
curl --help

--connect-timeout SECONDS  Maximum time allowed for connection
-m, --max-time SECONDS  Maximum time allowed for the transfer

...

--retry NUM   Retry request NUM times if transient problems occur
--retry-delay SECONDS  Wait SECONDS between retries
--retry-max-time SECONDS  Retry only within this period

上面是我整理的一部分跟时间有关系的参数, 虾米啊我们依次实验下.

连接超时参数 connect-timeout

说明

代码语言:javascript
复制
--connect-timeout SECONDS  Maximum time allowed for connection

示例

代码语言:javascript
复制
#这里我们设置超时时间为2s, 请求一个无法解析的地址
curl --connect-timeout 2 --url http://xxx.com

curl: (28) Connection timed out after 2002 milliseconds

“显示连接超时, 超时时间2002毫秒. 注意这个 warning 的时间可能每次统计不太一样, 一般会超过我们的预设值一点.

代码语言:javascript
复制
#对于一个对返回时间要求比较高的情况, 可以设置为浮点型精确到毫秒
curl --connect-timeout 0.3 --url http://xxx.com

curl: (28) Connection timed out after 300 milliseconds

请求超时时间 --max-time

说明

代码语言:javascript
复制
-m, --max-time SECONDS  Maximum time allowed for the transfer

示例

代码语言:javascript
复制
#这里我们设置超时时间为2s, 应用程序中sleep 2
curl --max-time 2 --url http://www.shuai.com

curl: (28) Operation timed out after 2002 milliseconds with 0 bytes received

connect-time 和 max-time 联合使用:

代码语言:javascript
复制
#这里我们使用了一个无法解析的地址
curl --connect-time 3  --max-time 2 --url http://xxx.com
>  curl: (28) Connection timed out after 2001 milliseconds

curl --connect-time 3  --max-time 4 --url http://xxx.com
>  curl: (28) Operation timed out after 4002 milliseconds with 0 bytes received

“这里我们发现返回结果为连接超时 2001 毫秒, 当共同使用时, 连接以最小时间的为准, 而返回时间已 max-time 限制为准.

请求重试 retry

说明

代码语言:javascript
复制
--retry NUM   Retry request NUM times if transient problems occur

示例

代码语言:javascript
复制
#同样,我们去请求一个 sleep 2 的地址
curl --max-time 0.1 --retry 3  --url http://www.shuai.com

> Warning: Transient problem: timeout Will retry in 1 seconds. 3 retries left.
> Warning: Transient problem: timeout Will retry in 2 seconds. 2 retries left.
> Warning: Transient problem: timeout Will retry in 4 seconds. 1 retries left.
> curl: (28) Operation timed out after 100 milliseconds with 0 bytes received

“我们发现重试了3次, 但它并不是失败后立刻重试, 而是第一次 1 s后重试, 第二次 2 s后重试, 第三次 4 s后重试,依次递增 (每次重试受 max-time 限制).

重试超时时间 retry-max-time

我们发现我们的 max-time 只是对单次请求做了时间限制, 进而去影响总的重试时间, 但是我们想在单位时间内完成重试该怎么做呢. 这里 curl 也提供了重试的超时时间 retry-max-time

代码语言:javascript
复制
curl --retry 3 --retry-max-time 2  --max-time 0.1 --url http://www.shuai.com

> Warning: Transient problem: timeout Will retry in 1 seconds. 3 retries left.
> Warning: Transient problem: timeout Will retry in 2 seconds. 2 retries left.
> curl: (28) Operation timed out after 101 milliseconds with 0 bytes received

“我们对重试总的超时时间设置为2s, 配置了3次重试, 但仅仅完成了两次重试就超时结束了.

重试延迟 retry-delay

我们在 请求重试 里面讲到, 这里的重试并不是失败后立刻重试的, 默认重试时间递增, 这里我们可以使用 retry-delay 控制重试的间隔.

代码语言:javascript
复制
#这里我们设置重试时间5s,重试3次
curl --retry 3 --retry-delay 5 --max-time 0.1  --url http://xxx.com

> Warning: Transient problem: timeout Will retry in 5 seconds. 3 retries left.
> Warning: Transient problem: timeout Will retry in 5 seconds. 2 retries left.
> Warning: Transient problem: timeout Will retry in 5 seconds. 1 retries left.
> curl: (28) Connection timed out after 101 milliseconds

“我们发现 Will retry in 变成了 5 s一次

php 使用 guzzle 包

Guzzle是一个PHP的HTTP客户端,用来轻而易举地发送请求,并集成到我们的WEB服务上.

快速安装

代码语言:javascript
复制
{
  "require": {
    "guzzlehttp/guzzle": "~5.3|~6.0"
  },
  "repositories": {
    "packagist": {
      "type": "composer",
      "url": "https://mirrors.aliyun.com/composer/"
    }
  }
}

执行 composer

代码语言:javascript
复制
composer install

示例代码(超时机制)

代码语言:javascript
复制
require "./vendor/autoload.php";


$client = new GuzzleHttp\Client();

$res = $client->request('GET',
    'http://xxx.com',
    [
        'connect_timeout' => 3,
        'timeout'         => 2,
    ]
);

echo $res->getBody() . PHP_EOL;

output:

代码语言:javascript
复制
PHP Fatal error:  Uncaught GuzzleHttp\Exception\ConnectException:
cURL error 28: Connection timed out after 2002 milliseconds
(see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
....

“我们配置了 connect_timeout 超时时间 3 s, timeout超时时间 2 s

guzzle 重试机制

重试机制比较麻烦一点, 需要使用 Middleware 来实现, 但也很好理解

代码语言:javascript
复制
require "./vendor/autoload.php";

$handlerStack = GuzzleHttp\HandlerStack::create();

//绑定中间件, 重试三次
$restryCount = 3;
$handlerStack->push(\GuzzleHttp\Middleware::retry(function () use (&$restryCount) {
    if (--$restryCount <= 0) {
        return false;
    }
    return true;
}, function () use ($restryCount) {
    return 1000; //毫秒
}));


$client = new GuzzleHttp\Client(['handler' => $handlerStack]);

$res = $client->request('GET',
    'http://xxx.xxx.com',
    [
        'connect_timeout' => 3,
        'timeout'         => 2,
    ]
);

echo $res->getBody() . PHP_EOL;

“在定义 retry 的时间, 你需要去实现是否继续重试, 重试的时间等策略, 提供了巨大的重试灵活性.

“值得注意的是 curl 的重试时间单位是秒, 而这里是设置的毫秒.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 呆呆熊的技术路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • curl 关于时间控制和重试的参数
  • 连接超时参数 connect-timeout
  • 请求超时时间 --max-time
  • 请求重试 retry
  • 重试超时时间 retry-max-time
  • 重试延迟 retry-delay
  • php 使用 guzzle 包
    • guzzle 重试机制
    相关产品与服务
    命令行工具
    腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档