У меня есть ряд пхп-скриптов, которые подсоединяются как клиенты к REST API стороннего сервиса. Все скрипты используют один логин/пароль для аутентификации. Проблема в том, что API-сервер принимает только одно соединение одновременно. Соответственно, если несколько скриптов пытаются подключиться к API-серверу одновременно, то они получают ошибку.
Как можно организовать очередь запросов? Я думал о том, чтобы создать запись в БД или lock-файл при открытии соединения с сервисом и убирать его по окончанию соединения, но это не решает вопрос очерёдности запросов.
Почему бд не решает вопрос очередности? Записывается в бд скрипты в очередности запуска. Потом пишите скрипт, который проверяет, если ли записи на выполнение в бд, если есть - берет запись и запускает соответствующий скрипт, выставляя в бд флаг, например, is_executed, в true. И по крону можете каждую минуту запускать этот срипт.
А можно не страдать фигней а воспользоваться менеджерем очередей, я привел одно из таких решений. Очередь хранится в reddis, блокировки и прочее хэндлит оно, вы просто забираете из очереди очередное сообщение/таск и обрабатываете.
А можно на пальцах объяснить правильно ли я понял концепцию работы? Например, пользователь заходит на страницу сайта, которая содержит результаты get-запроса к api, php-скрипт отправляет задание на выполнение этого запроса к серверу очередей и ждёт когда задание будет выполнено (периодически проверяет статус?), получает результат и выводит его на странице. Так?
Олег Абражаев: оно не лучше, оно проще. Если у вас все воркеры на одном сервере и нужно что-то простенькое просто распаралелить нет смысла подключать тяжелую арлтелерию. В контексте задачи быть может и не нужно вообще ничего, один процесс воркер. никаких гонок у нас нету... даже лочить ничего не нужно по идее.
Сергей Протько: а если предположить, что контекст задачи все же предпологает высокую нагрузку, отказоустойчивость и возможность масштабирования. Какое решение вы бы рекомендовали тогда? Писать свое на основе того же Gearman или что-то из готовых решений?
И если немного расширить описанную задачу. Что если таких однозапросных API несколько, и когда поступает один запрос в очередь его надо параллелить на N (к-во API) которые надо опросить. Как лучше тут решать? Делать форки воркеров или же делать две очереди (основные запросы и распараллеленые воркеры)?
Олег Абражаев: я бы в этом случае взял rabbitmq и настроил несколько очередей, по одному воркеру на кажую апишку, потом можно спокойно разнести их по сервакам и т.д.
umbertone: у вас две очереди, а не два воркера по сути. resque не справится если у вас воркер на другом сервере. Хотя думаю и тут можно выкрутиться, но если воркеры на нескольких серверах (например для конвертации видио) - то тут уже стоит смотреть в сторону rabbitqm и ему подобных которые гарантируют доставку, надежны и имеют массу вариантов обслуживания и доставки сообщений.
Если у вас сложная логика меседжей, нужна возможность запускать таски по рассписанию, с повторениями и т.д. - то тут лучше взять gearman какой или activemq. Если нужен простой и быстрый pub/sub или очень эффективная шина данных (например между основным приложением и чатиком) - имеет смысл смотреть на zeromq.
У меня просто ряд задач надо запускать по расписанию и я думал это кроном делать, но если, например, gearbox это умеет делать в добавок к очередям, то посмотрю в его сторону