cronjob выполняет скрипт с примерно 100 URL-адресами curl - плохая практика?

Я пишу задание cron, которое выполнит сценарий, который загрузит до ~ 100 URL-адресов, каждый URL-адрес содержит данные, которые будут сохранены в memcached при выполнении. Время завершения / загрузки каждого URL-адреса может занять от 10 секунд до 15 минут, каждый URL-адрес загружает данные из базы данных и возвращает результат в виде json и кэширует результат. Основная идея этого скрипта - кэшировать полученные данные утром (00:00 - до того времени, которое потребуется для кеширования всего), чтобы утром людям не пришлось ждать, пока данные снова будут кешированы. .

URL-адреса - это URL-адреса API. Будет ли curl ждать окончания каждого выполнения? считается ли это плохой практикой? До этого момента кеша не было, поэтому я пытаюсь его реализовать, кэшировать данные наиболее часто используемых URL-адресов на 24 часа или аналогичное время.


person PaaPs    schedule 02.07.2018    source источник
comment
Возможно, вам стоит использовать язык, который лучше реализует асинхронные задачи. Также существуют бессерверные решения (такие как OpenWhisk), которые могут быть полезны для того, что вам нужно. Если каждый завиток не использует тысячу процентов ЦП, вы можете запускать несколько действий одновременно. Большим преимуществом является то, что вы можете работать с помощью микросервисов (cURL на 1 URL, затем запись в базу данных, затем данные кеширования ...). Большое преимущество в том, что вы можете продолжать использовать любой язык, какой захотите. Надеюсь, это поможет. (Edit) И, как сказал @ErwinMoller, следите за журналами, они будут вашими лучшими друзьями   -  person Zyigh    schedule 02.07.2018
comment
Извините, но страницы, которые загружаются за 15 минут, нуждаются в исправлении.   -  person Lawrence Cherone    schedule 02.07.2018
comment
Я согласен с вами, что загрузка данных не должна занимать 15 минут, но это записи за весь год, точнее, около 160 000 000 записей или более, mysql требует много времени, чтобы получить столько данных . Скрипт был написан не мной, я попробую поискать способы оптимизации запросов и сортировки в этой штуке, но пока мне нужно какое-то решение ...   -  person PaaPs    schedule 02.07.2018


Ответы (2)


Что касается интеграции curl ...

Будет ли curl ждать окончания каждого выполнения?

Это зависит от того, как вы используете библиотеку curl. Вы пометили вопрос с помощью «php» и «php-curl» - так что, похоже, вы обращаетесь к процедурам curl из PHP.

Если вы используете интерфейс curl easy примерно следующим образом:

  • инициализировать простой дескриптор с помощью $req = curl_init()
  • установить URL и другие параметры с помощью curl_setopt()
  • выполнить (одиночный) запрос с curl_exec($req)
  • закрыть или сбросить запрос с помощью curl_close($req) или curl_reset($req)

тогда, естественно, вам придется ждать завершения каждого запроса, прежде чем начинать следующий.

Альтернативой является использование интерфейса multi (см. Ниже), который позволяет нескольким запросам работать одновременно.

считается ли это плохой практикой?

Если вы отправляете такое большое количество сетевых запросов - а каждый запрос потенциально занимает такое много времени - я думаю, что это, безусловно, далеко от идеала. Было бы предпочтительнее использовать интерфейс curl multi, если это вообще возможно.

multi интерфейс

Как поясняется в документации по curl, мультиинтерфейс (в отличие от ' легкий интерфейс)

Включите [s] несколько одновременных передач в одном потоке, не усложняя это для приложения ...

Мой PHP очень слаб, поэтому - вместо того, чтобы публиковать полный пример сам - я вместо этого отсылаю вас к документации PHP на _ 10_ и связанные функции.

Вкратце, идея состоит в том, что вы по-прежнему инициализируете свои ручки curl таким же образом. (В документации PHP это явно не упоминается, но простой дескриптор curl иногда называют «простым» дескриптором - чтобы отличить его от «мульти» дескриптора.)

$req1 = curl_init();
$req2 = curl_init();
// Set URL and other options using `curl_setopt(...)`

(Я опускаю здесь все проверки ошибок для краткости.) Однако вместо вызова curl_exec(...) вы вместо этого создаете экземпляр multi,

$mh = curl_multi_init();

добавьте easy дескрипторы к вашему вновь созданному экземпляру multi,

curl_multi_add_handle($mh, $req1);
curl_multi_add_handle($mh, $req2);

а затем (вместо вызова curl_exec() для одного easy дескриптора) периодически вызывать curl_multi_exec(...) в цикле:

curl_multi_exec($mh, $running);

Переменная $running будет обновлена, чтобы указать, есть ли еще выполняющиеся запросы, поэтому - как только $ running станет ложным - вы можете выйти из цикла и завершить его.

Когда закончите, не забудьте прибраться.

curl_multi_remove_handle($mh, $req1);
curl_multi_remove_handle($mh, $req2);
curl_multi_cleanup($mh);

Оптимизация под большое количество запросов

Вместо использования отдельных переменных для каждого запроса - как в $req1, $req2 и т. Д. - вы можете использовать массив запросов - возможно, загружая соответствующие URL-адреса из текстового файла (что, как я подозреваю, вы уже делаете).

person David Collins    schedule 02.07.2018

Убедитесь, что у вашего скрипта нет тайм-аута, поэтому запускайте его из BASH или чего-то еще, НЕ через сервер (Apache, NGINX и т. Д.).

Также: убедитесь, что ваши команды curl ждут достаточно долго, посмотрите спецификации curl.

https://unix.stackexchange.com/questions/94604/does-curl-have-a-timeout/94612

Последнее: убедитесь, что вы не ошиблись, если 1 из 100 выйдет из строя.

Если вы можете в разумных пределах удовлетворить / решить эти 3 возможные проблемы, я думаю, у вас все будет в порядке. (Я всегда отправляю результат на свою почту, чтобы следить за ним)

person Erwin Moller    schedule 02.07.2018