В настоящее время я пытаюсь реализовать очередь заданий в php. Затем очередь будет обрабатываться как пакетное задание и должна иметь возможность обрабатывать некоторые задания параллельно.
Я уже провел некоторые исследования и нашел несколько способов его реализации, но я не знаю их преимуществ и недостатков.
Например, выполните параллельную обработку, вызвав скрипт несколько раз через fsockopen
как описано здесь:
Простая параллельная обработка в PHP
Другой способ, который я нашел, – использовать функции curl_multi
.
curl_multi_exec PHP-документы
Но я думаю, что эти два способа добавят слишком много накладных расходов для создания пакетной обработки в очереди, которая должна в основном работать на фоне?
Я также читал о pcntl_fork
также кажется способом справиться с этой проблемой. Но похоже, что это может стать действительно грязным, если вы действительно не знаете, что делаете (например, я на данный момент;)).
Я также посмотрел на Gearman
, но там мне также нужно было бы порождать рабочие потоки динамически по мере необходимости, а не просто запускать несколько, и пусть сервер задания передач отправит его свободным рабочим. Тем более, что потоки должны выполняться чисто после выполнения одного задания, чтобы не запускать возможные утечки памяти (код может быть не идеальным в этом вопросе).
Gearman Приступая к работе
Поэтому мой вопрос: как вы обрабатываете параллельную обработку в PHP? И почему вы выбираете свой метод, какие преимущества / недостатки могут иметь разные методы?
Спасибо за любой вклад.
Я использую exec()
. Его легко и чисто. Вам в основном нужно создать диспетчер потоков и сценарии потоков, которые будут делать то, что вам нужно.
Мне не нравится fsockopen()
потому что он откроет соединение с сервером, которое будет fsockopen()
и может попасть в лимит подключения Apache
Мне не нравятся функции curl
по той же причине
Мне не нравится pnctl
потому что ему нужно расширение pnctl, и вам нужно отслеживать отношения родителя / ребенка.
никогда не играл с редуктором …
Ну, я думаю, у нас есть 3 варианта:
A. Многопоточность:
PHP не поддерживает многопоточность. Но есть одно расширение PHP (экспериментальное), называемое pthreads ( https://github.com/krakjoe/pthreads ), которое позволяет вам делать именно это.
B. Многопроцессорный процесс:
Это можно сделать тремя способами:
C. Распределенная параллельная обработка:
Как это работает:
Client
приложение отправляет данные (сообщение AKA) «может быть форматировано JSON» в Engine (MQ Engine) «может быть локальным или внешним веб-сервисом» MQ Engine
хранит данные «в основном в памяти и, возможно, в базе данных» внутри очередей (вы можете определить имя очереди) Client
приложение запрашивает MQ Engine для обработки данных (сообщений) в порядке (FIFO или на основе приоритета) «вы также можете запрашивать данные из конкретной очереди». Некоторые двигатели MQ:
Больше их можно найти здесь: http://queues.io
Если ваше приложение будет запущено в среде unix / linux, я предлагаю вам перейти с опцией forking. В основном это детская игра, чтобы заставить ее работать. Я использовал его для менеджера Cron и имел код для его возврата к кодировке Windows, если форкировка не была вариантом.
Опции запуска всего скрипта несколько раз, как вы заявляете, добавляют довольно много накладных расходов. Если ваш скрипт мал, это может быть не проблема. Но вы, вероятно, привыкнете к параллельной обработке в PHP по тому, как вы решили идти. И в следующий раз, когда у вас есть работа, которая использует 200 МБ данных, это может быть проблемой. Таким образом, вам лучше научиться тому, с чем вы можете справиться.
Я также тестировал Gearman, и мне это очень нравится. Есть несколько вещей, о которых стоит подумать, но в целом он предлагает очень хороший способ распространения работ на разных серверах, работающих на разных приложениях, написанных на разных языках. Помимо настройки, фактически используя его из PHP или любого другого языка в этом отношении, … еще раз … дети играют.
Это вполне может быть излишним для того, что вам нужно сделать. Но это откроет вам глаза на новые возможности, связанные с обработкой данных и рабочих мест, поэтому я бы рекомендовал вам попробовать Gearman только для этого.
Я предпочитаю exec () и gearman. Функция exec () проста и не требует соединения и меньше потребляет память. gearman должен нуждаться в соединении сокета, и работник должен взять некоторую память. Но gearman более гибкий и быстрее, чем exec (). И самое главное, что он может развернуть рабочего на другом сервере. Если работа – это время и ресурс. Я использую gearman в моем текущем проекте.
Я использую PHP pnctl – это хорошо, пока вы знаете, что делаете. Я понимаю вашу ситуацию, но я не думаю, что это что-то трудно понять в нашем коде, мы просто должны быть немного более сознательными, чем когда-либо, при реализации очереди JOB или параллельного процесса.
Я чувствую, что до тех пор, пока вы правильно его кодируете и убедитесь, что поток полностью выключен, вы должны учитывать ПАРАЛЛЕЛЬНЫЙ ПРОЦЕСС при реализации.
Где вы можете делать ошибки:
Взгляните на этот пример – https://github.com/rakesh-sankar/Tools/blob/master/PHP/fork-parallel-process.php .
Надеюсь, поможет.
Метод, описанный в разделе «Простая параллельная обработка в PHP», совершенно пугает – принцип в порядке – но реализация ??? Как вы уже указали, curl_multi_ fns обеспечивают гораздо лучший способ реализации этого подхода.
Но я думаю, что эти два способа добавят довольно много накладных расходов
Да, вам, вероятно, не нужен HTTP-стек клиента и сервера для передачи задания, но если вы не работаете в Google, время разработки намного дороже, чем затраты на оборудование, и есть много инструментов для управления HTTP / анализ производительности – и есть определенный стандарт, охватывающий такие материалы, как уведомления о состоянии и аутентификация.
Многое из того, как вы реализуете решение, зависит от требуемой целостности транзакций и требует ли вам обработки в порядке.
Из упомянутых подходов я бы рекомендовал сосредоточиться на методе HTTP-запроса с помощью curl_multi_. Но если вам нужен хороший транзакционный контроль / доставка по заказу, вам обязательно нужно запустить демон брокера между источником сообщений и обработчиками (есть хорошо написанный однопоточный сервер, подходящий для использования в качестве основы для брокера здесь ). Обратите внимание, что обработчики должны обрабатывать одно сообщение за раз.
Если вам требуется масштабируемое решение, взгляните на правильную систему очередей сообщений, такую как RabbitMQ .
НТН
C.