Функция curl очень мощная и имеет много параметров.Мы не только часто используем в командной строке, но также имеем реализации, аналогичные расширениям curl в php, а также обеспечиваем очень хорошую поддержку библиотеки libcurl.
кудрявый проект:github.com/curl/curl
параметры curl о контроле времени и повторных попытках
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 SECONDS Maximum time allowed for connection
Пример
#这里我们设置超时时间为2s, 请求一个无法解析的地址
curl --connect-timeout 2 --url http://xxx.com
curl: (28) Connection timed out after 2002 milliseconds
Отображается время ожидания соединения, и время ожидания составляет миллисекунды 2002. Обратите внимание, что время этого предупреждения может не быть одинаковым каждый раз, и обычно оно превышает заданное нами значение.
#对于一个对返回时间要求比较高的情况, 可以设置为浮点型精确到毫秒
curl --connect-timeout 0.3 --url http://xxx.com
curl: (28) Connection timed out after 300 milliseconds
тайм-аут запроса --max-time
инструкция
-m, --max-time SECONDS Maximum time allowed for the transfer
Пример
#这里我们设置超时时间为2s, 应用程序中sleep 2
curl --max-time 2 --url http://www.shuai.com
curl: (28) Operation timed out after 2002 milliseconds with 0 bytes received
Используйте время подключения и максимальное время в комбинации:
#这里我们使用了一个无法解析的地址
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. При совместном использовании соединение подвергается минимальному времени, а время возврата ограничено максимальным временем.
запросить повторную попытку повторить
инструкция
--retry NUM Retry request NUM times if transient problems occur
Пример
#同样,我们去请求一个 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 с в первый раз, повторил попытку через 2 с во второй раз и повторил попытку через 4 с в третий раз, увеличивая по порядку ( Каждая попытка ограничена максимальным временем).
тайм-аут повтора
Мы обнаружили, что наше максимальное время устанавливает ограничение по времени только для одного запроса, что, в свою очередь, влияет на общее время повторной попытки, но что нам делать, если мы хотим завершить повторную попытку в единицу времени.Здесь curl также предоставляет время ожидания повторной попытки. максимальное время повторной попытки
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
Мы установили общий тайм-аут повтора на 2 с, настроили 3 повтора, но тайм-аут закончился после того, как были завершены только два повтора.
задержка повторной попытки
Как мы упоминали в разделе «Повторная попытка», повторная попытка здесь не является повторной попыткой сразу после сбоя, время повторной попытки по умолчанию увеличивается, здесь мы можем использовать задержку повторной попытки для управления интервалом повторной попытки.
#这里我们设置重试时间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
Мы обнаружили, что повторная попытка в один раз превратилась в 5 с.
php использует пакет guzzle
Guzzle — это HTTP-клиент PHP для простой отправки запросов и интеграции с нашими веб-сервисами.
Быстрая установка
{
"require": {
"guzzlehttp/guzzle": "~5.3|~6.0"
},
"repositories": {
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
}
}
казнить композитора
composer install
Пример кода (механизм тайм-аута)
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;
вывод:
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 с и период тайм-аута на 2 с.
механизм повторных попыток жрать
Механизм повторных попыток немного сложнее и должен быть реализован с помощью промежуточного программного обеспечения, но он также хорошо понятен.
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;
Во время определения повторных попыток необходимо реализовать такие стратегии, как необходимость продолжения повторных попыток и время повторных попыток, что обеспечивает большую гибкость повторных попыток.
Стоит отметить, что единицей времени повтора curl является секунда, а здесь заданы миллисекунды.