Я хочу запускать несколько задач cURL в фоновом режиме, используя PHP на Ubuntu.
Есть несколько способов, но я не уверен, какой из них выбрать.
Способ 1: использовать ОС CURL
<?php
require_once('database.php');
$db = new Database; // SQLite3 database
$query = $db->query("SELECT * FROM users");
while ($user = $query->fetchArray(SQLITE3_ASSOC)) {
exec("nohup curl --url http://example.com/?id=".$user['id']." &");
}
?>
Способ 2: http://www.paul-norman.co.uk/2009/06/asynchronous-curl-requests
<?php
require_once('database.php');
$db = new Database; // SQLite3 database
$query = $db->query("SELECT * FROM users");
while ($user = $query->fetchArray(SQLITE3_ASSOC)) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/?id=".$user['id']);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);
curl_exec($ch);
curl_close($ch);
}
?>
Я не понимаю, как работает способ 2. Может кто-нибудь объяснить это? Какой путь выбрать, если у меня 100 000 — 500 000 пользователей? Обратите внимание, что cURL может выполнять свою работу в течение 2 — 8 секунд. Я не уверен, что способ 2 будет работать, потому что, если он может выполнить свою работу в течение нескольких секунд, и время ожидания установлено на 1 мс — будет ли соединение прекращено, когда это не будет сделано?
РЕДАКТИРОВАТЬ: Способ 2 не работает для меня, потому что требуется больший тайм-аут. Способ 1 может привести к замедлению работы компьютера. Я сделал это: когда мне нужен идентификатор всех пользователей, я не делаю 1000 запросов, но отправляю базу данных (SQLite) на другой сервер. Затем он ищет идентификаторы.
Ваш первый код будет запускать запрос curl в фоновом режиме, то есть цикл tle будет выполняться N раз, выдавая N запрос curl, и скрипт PHP будет завершен (независимо от запроса curl).
Второй вариант выдаст запрос CURL, и веб-сервер отправит вам статус 504 (время ожидания), однако сценарий все еще выполняется в фоновом режиме — он просто прекращает отправку данных клиенту.
Тем не менее, я не уверен с тайм-аутом 1 мс, потому что connect_time может быть выше.
Других решений пока нет …