PHP: многопоточный PHP / веб-сервисы? - PullRequest
3 голосов
/ 28 ноября 2009

Привет всем!

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

Однако я пытаюсь выяснить, как обрабатывать от 1000 до 10000 запросов каждую минуту или каждые 5 минут.

В основном поток: 1) Получить список предметов из базы данных (от 1000 до 10000 предметов) 2) Сделайте запрос API POST для каждого элемента 3) Принять возврат данных, обработать данные, обновить базу данных

Очевидно, что один экземпляр PHP, выполняющий это в цикле, был бы невозможен.

Мне известно, что PHP не является многопоточным языком.

Я попробовал решение CURL, в основном: 1) Получить список предметов из базы данных 2) Инициализировать сеанс мульти керла 3) Для каждого элемента добавить сеанс скручивания для запроса 4) выполнить сеанс multi curl

Таким образом, вы можете представить, что происходит 1 000–10 000 запросов GET ...

Это было нормально, примерно 100-200 запросов происходили примерно через минуту или две, однако только 100-200 из 1000 элементов фактически обрабатывались, я думаю, что я достигаю некоторого ограничения Apache или MySQL?

Но это добавляет задержку, это почти как выполнение DoS-атаки на себя.

Мне интересно, как бы вы справились с этой проблемой? Что делать, если вам нужно было сделать 10 000 запросов веб-службы и 10 000 обновлений MySQL на основе данных, возвращаемых веб-службой ... И это нужно сделать как минимум за 5 минут.

Я использую PHP и MySQL с Zend Framework.

Спасибо!

Ответы [ 7 ]

1 голос
/ 28 ноября 2009

Мне пришлось сделать нечто подобное, но с Facebook, обновляя 300 000+ профилей каждый час. Как предлагает grossvogel, вам нужно использовать много процессов, чтобы ускорить процесс, потому что сценарий тратит большую часть своего времени в ожидании ответа. Вы можете сделать это с помощью разветвления, если в вашей установке PHP есть поддержка разветвления, или вы можете просто выполнить другой сценарий PHP через командную строку.

exec('nohup /path/to/script.php >> /tmp/logfile 2>&1 & echo $!'), $processId);

Вы можете передать параметры (getopt) сценарию php в командной строке, чтобы сообщить ему, какой «пакет» обрабатывать. Вы можете попросить главный сценарий выполнить цикл ожидания / проверки, чтобы проверить, все ли еще выполняются сценарии, проверив идентификаторы процесса. Таким образом, я протестировал до 100 сценариев, выполняемых одновременно, и в этот момент загрузка ЦП может стать достаточно высокой.

Объедините несколько процессов с помощью нескольких скручиваний, и вы легко сможете делать то, что вам нужно.

1 голос
/ 28 ноября 2009

Мои два предложения: (а) провести некоторый сравнительный анализ, чтобы выяснить, где ваши настоящие узкие места, и (б) по возможности использовать пакетную обработку и кэширование.

Mysqli допускает запросы с несколькими утверждениями, поэтому вы, безусловно, можете пакетно обновлять эти базы данных.

Однако http-запросы к веб-сервису более вероятны. Проверьте API, который вы используете, чтобы увидеть, можете ли вы получить больше информации за один звонок, может быть? Чтобы разбить работу, может быть, вы хотите, чтобы один мастер-сценарий выкладывался на несколько отдельных процессов, каждый из которых выполняет вызов API и сохраняет результаты в файле или в кэше памяти. Мастер может периодически читать результаты и обновлять БД. (Осторожно повернуть хранилище данных для безопасного чтения и записи несколькими процессами.)

0 голосов
/ 28 ноября 2009

Это правда, что PHP не многопоточный, но он, безусловно, может быть настроен с несколькими процессами.

Я создал систему, похожую на ту, которую вы описываете. Он работает в цикле и в основном является фоновым процессом. Он использует до 8 процессов для пакетной обработки и один процесс управления.

Это несколько упрощено, потому что мне не нужно общаться между процессами. Все находится в базе данных, поэтому каждый процесс создается с полным контекстом, взятым из базы данных.

Вот базовое описание системы. 1. Запустите процесс контроля 2. Проверьте базу данных на новые вакансии 3. Создайте дочерний процесс с данными задания в качестве параметра 4. Ведите таблицу дочерних процессов, чтобы иметь возможность контролировать количество одновременных процессов.

К сожалению, не представляется распространенной идеей использовать PHP для приложений такого типа, и мне действительно пришлось написать обертки для функций низкого уровня.

В руководстве есть целый раздел об этих функциях, и, похоже, существуют методы для разрешения IPC.

PCNTL имеет функции для управления разветвлением / дочерними процессами, а Семафор охватывает IPC.

Интересной частью этого является то, что я могу отключить реальный код PHP, а не выполнять другие программы.

0 голосов
/ 28 ноября 2009

Спасибо всем за удивительные и быстрые ответы!

Совет от Brent Baisley и e-satuns работает хорошо, вместо того, чтобы выполнять подпроцессы с использованием CURL, как я делал раньше, разветвление снимает большую нагрузку, оно также прекрасно справляется с проблемами с помощью max apache подключения ограничение.

Еще раз спасибо!

0 голосов
/ 28 ноября 2009

Вы можете следовать советам Брента Бэйсли для простого случая использования.

Если вы хотите создать решение для роботов, вам нужно:

  • настроить представление действий в таблице в базе данных, которая будет вашей очередью процессов;
  • установить скрипт, который выталкивает эту очередь и обрабатывает ваши действия;
  • установить демон cron, который запускает этот скрипт каждые x.

Таким образом, вы можете запустить 1000 PHP-скриптов, используя возможности параллелизма ОС и не зависая, когда ebay пытается ответить.

Реальным преимуществом этой системы является то, что вы можете полностью контролировать огневую мощь, которую вы бросаете в своей задаче, настраивая:

  • количество запросов, выполняемых одним PHP-скриптом;
  • порядок / номер / тип / приоритет действия в очереди;
  • число или сценарии, которые запускает демон cron.
0 голосов
/ 28 ноября 2009

Если вы не можете перейти на другой язык, попробуйте выполнить это обновление, возможно, как php-скрипт, который работает в фоновом режиме, а не через apache.

0 голосов
/ 28 ноября 2009

Чтобы лучше понять ваши требования, вы должны реализовать свое решение только на PHP? Или вы можете связать часть PHP с другой частью, написанной на другом языке?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...