Добрый день.
На данный момент существует система, которая является коннектором к нескольким апи со сложной бизнес логикой в промежутке между получением запроса, отправкой в API и ответом.
Я хочу переписать эту систему для обеспечения более высокой производительности, отказоустойчивости и возможности масштабирования.
Выше перечисленное - это требования.
Теперь задача.
Есть несколько внешних клиентов для back-end коннектора. Клиенты могут отправлять запросы в определенном формате. От каких-то клиентов больше, от каких-то меньше, все приходят на один порт. Назовем запрос от клиента Port Request.
Далее система должна осуществлять предобработку запроса, логирование и по некой бизнес-логике параллелить запрос на несколько. Эти несколько новых запросов назовем Worker Request. В них содержаться уже данные для отправки в конкретный API и они должны выполняться параллельно либо асинхронно.
В это время головной процесс ждет ответа от каждого Worker Request.
По получению всех ответов (или ошибки по таймауту от каких-то API) головной процесс должен проводить пост обработку и сформировать из всех ответов Worker Request один ответ Port Request, залогировать его и отдать клиенту.
Так должен выполняться один цикл обработки одного запроса от клиента.
Запросов есть несколько типов и одни запросы могут быть зависимы от данных предыдущих запросов (т.е. например на одном из запросов на предпроцессинге надо выбрать данные из БД по ИД от предыдущего запроса). Следовательно логи запросов является так же рабочими единицами, которые должны храниться как минимум 30 дней.
-------
Ниже следует описание текущей системы.
Текущая система работает в точности как описано в ТЗ, но реализация не оптимальна. Используется php + mysql. Mysql играет роль как хранилища, так и очереди. Приходящий в контексте web сервера Port Request пишется в БД, далее бизнес логика генерирует Worker Request (N шт), они тоже пишутся в БД. Далее их подхватывает демон в консоли и параллелит через форки используя библиотеку Spork. При взятии из БД Worker делается выборка с блокировкой до обновления. Так же используется memcached для кеширования ответа каждого Worker.
Плюсы данного решения - логи в БД, т.е. можно посмотреть логи запросов.
Минусы данного решения в той же БД, я вижу, что масштабирование затруднительно, вся нагрузка ложиться на БД (много записи и чтения).
------
Суть этого в опроса в идеях и предложениях - как решить задачу наилучшим образом? Какие использовать подходы (очереди, форки, демоны) ? Какие инструменты (gearman, redis, библиотеки) ? Технологии (сейчас php, можно другие) ?
Сейчас я смотрю в сторону таких решений:
- Логи запросов писать в Mongo. (Логи в бизнес логике являются так же рабочей единицей и по ИД Port Request или Worker Request берутся данные для работы.)
- Очередь организовать через Gearman (или др). (тут не понятно не создаст ли это owerflow над текущим решением, т.к. логи все равно писать придется)
- Не понятно как парралелить Worker, оставить так же форки или же сделать вторую очередь. Первая очередь - Port Request, вторая - Worker Request.