×

Обоснование использования сервера очередей

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Добрый день. Интересует мнение опытных людей, которые разрабатывали API или работали с серверами очередей.

Задача: реализовать своей REST API сервер, который будет выступать посредником для API другого сервиса (в моем случае Google). Будет 2 вида клиентов (мобильные приложения, веб приложения) которые обращаются к моему API за информацией, а API в свою очередь берет определенные данные из Google.

Соответственно возможны задержки в ответах. Кроме того каждый клиенты может поставить отложенную задачу (создавать отчет каждые 12 часов или отправлять мне email каждые 2 часа, если были изменения).

Вопрос: Нужен ли в подобном сервисе сервер очередей, и если да, то он выступает посредником между клиентом и мои API или посредник между API и Google ?

Сервер будет использовать PHP как backend часть и Angular5 как фронт часть для веб приложения.

P.S Если есть кто из Днепра и готов дать оффлайн консультацию, я готов заплатить за это. Очень важно мнение знающего человека.

Спасибо заранее за ответы.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Добрый день.

Соответственно возможны задержки в ответах.

Очередя нужны когда клиент не ждет online данные, то есть клиент запросил сделать отчет и как доделается скинуть его на e-mail, в таком случае для offline задач стоит использовать сервера очередей.

Кроме того каждый клиенты может поставить отложенную задачу (создавать отчет каждые 12 часов или отправлять мне email каждые 2 часа, если были изменения).

С вашей нагрузкой для данных задач достаточно кронов. Лучше решать проблемы по мере их поступления.

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

Я бы на вашем месте не тратил время на сервера очередей.

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

highscalability.com/...​e-scaling-to-1-billi.html
Queues were a saviour. When passing work between components put it into a queue. You get a nice little buffer. (Reddit uses RabbitMQ for message queuing)

Александр, тут 2 задачи, которые по разному можно решать. Понятно что проще всего «в лоб», ничего не выдумывать:
1. в API просто curl / guzzle.
2. для задач по расписанию cron-скрипт

Но, нужно быть готовым к тому, что количество php-worker’ов может начать не хватать в случае определённого количество запросов к api и долгом ответе внешних сервисов. Тогда бекенд апи делать либо через event loop подход (reactphp, amphp) — из плюсов — большее количество одновременных коннектов конткретно в данной задаче и меньшая нагрузка на сервер по памяти. Но нужно ставить какой-то демон, типа superviserd, чтоб следил за упавшими процессами и перезапускал. Не забыть запустить несколько таких процессов на всякий случай и балансировать на них http трафик через nginx.
Либо же делать асинхронное API — пришёл запрос, сгенерили уникальный id, поставили задачу в очередь. Клиенту вернули этот id. Чтоб он периодически дёргал статус выполнения задачи по api. А там уже пул php-процессов (тоже запускаемых через supervisord или подобное) слушает очередь и выполняет задачи и обновляет по id статусы/результаты. Асинхронные API обычно менее удобные в использовании чем синхронные, так что здесь выбор за вами.

Ну и задачи по расписанию. Понятно что нужно где-то это расписание хранить, по крому раз в N-минут/часов выбирать и исаольнять. Всё просто до тех пор пока задач мало, либо они очень быстро выполняются. Если нужно одновременно обработать 1000 задач, каждая по 10 сек. То в случае последовательного выполнения последний польователь получит результат на 2.5 часа позже, что как бы ой. Нужно их обрабатывать паралельно. Один из простых вариантов действительно через очередь — один cron-скрипт выгребает актуальные задания, ставит их в очередь и всё. Это быстро. Дальше уже пул php-процессов, слушающих очередь паралельно выполняют задания и профит. Можно и без очереди, один cron-процесс через fork создаёт друие процессы-обработчики, но в этом случае у нас нет возможности масштабирования обработки по серверам. Можно конечно этот вариант проапгрейдидь чтоб выполнять на разных серверах обработку, тогда нужно делать блокировку очереди чтоб не возникало race conditions при одновременных запросах к получению актуальных задач. Если очередь в базе, то решается через select ... for update skip locked (в mysql skip locked появился только в mysql 8, но можно накостылить и просто с for update).

В общем. Если пока не понятен уровень возможной нагрузки, выстрелит или нет. То делай в лоб, без очередей, асинхронности и т.д. Простая логика работающая под php-fpm для api и cron для задач по расписанию. А когда будет понятно что количество запросов растёт, fpm status показывает active processes приближается к total processes или уже появляются max children reached. Тогда рефакторить / масштабировать. Как временный вариант для быстрого затыкания дыры всё равно не сложно доставить новый сервер для api и на него трафик забалансировать (конечно когда уже с первого сервера всё выжали, выкрутили максимальное количество fpm процессов что память позволяет, cpu в таких задач сильно нагружаться не должно).

Спасибо за такой развернутый ответ. На самом деле сразу нагрузка большая не ожидается вообще, оптимистические прогнозы это 500 активных юзеров за год, которые пользуются сервисом каждый день и проводят на нем около часа максимум. Все остальное время это запланированные задачи, которые формируют отчеты и отправляют уведомления на email или смс не чаще чем раз в час (и то только при критических изменениях). Кроме того, не имея опыта в серверах очередей, разработка затянется на недельку вторую, а это, как часто бывает, не интересно компании).

Проблемы, которые решает сервер очередей:

  • Уменьшить время ответа апи на запрос клиента до приемлемых пары секунд, если его невозможно уменьшить оптимизацией (обработка тяжелых файлов, 3rd-party API)
  • Распределить нагрузку

Если у вас есть такие проблемы, то вам нужен сервер очередей. Если нет — не нужен.

Сервер очередей хранит очередь задач. Например если вам нужно получить от пользователя и обработать большой файл, и его обработка может занять больше чем 30 секунд, то вы получаете файл от пользователя и кладёте его во временную папку, создаете задачу и пользователю отвечаете «файл загружен и обрабатывается». То же самое если нужно работать с каким-то третьим апи, который долго отвечает (сомневаюсь что в случае апи гугла это нужно, если честно) — кладем задачу в очередь и отвечаем пользователю что запрос обрабатывается. Это вы делаете в вашем апи. Кроме вашего апи у вас должна быть постоянно работающая программа (daemon, worker), которая берет задачи из очереди и их выполняет. Таких воркеров может быть несколько. Сервер очередей выступает посредником между вашими воркерами и вашим апи.

Ваш апи должен уметь:

  • Сохранить задачу в очередь и вернуть клиенту какой-то идентификатор задачи
  • Отдавать по идентификатору задачи статус задачи
  • Отдавать список задач конкретного пользователя

Воркеры должны уметь:

  • Взять задачу из очереди и выполнить её
  • Сообщить серверу очередей что всё готово, чтобы ваш апи мог увидеть что задача завершилась

Клиент должен уметь:

  • Показывать список задач и их статусы, чтобы пользователь мог видеть прогресс/ошибки

«Создавать отчет каждые х часов» тоже можно наверное решать при помощи сервера очередей, если воркер после выполнения задачи будет добавлять в очередь такую же, но через х часов. Но можно и просто скрипт раз в минуту кроном запускать, если клиентов не много и задачи не тяжелые.

Проблемы, которые решает сервер очередей:

Уменьшить время ответа апи на запрос клиента до приемлемых пары секунд, если его невозможно уменьшить оптимизацией (обработка тяжелых файлов, 3rd-party API)
Распределить нагрузку

Еще — улучшение availability сервиса. Если, к примеру, гугол лежит, вы все равно сможете принимать запросы от кастомеров, и ложить их в очередь. Кастомеры не будут видеть никаких ошибок от ваших API, а их запросы будут обработаны когда гугл поднимется, но попизже.

Гугл жестко банит за скрейпинг его сервисов, как только вы начнете дергать гугл хоть в какой то мере большей, чем обычный человек пользователь вас быстро вычислят и забанят. Исключение — публичные апи гугла, на которых свои квоты. Но зачем посредник для публичных апи вопрос открытый.

Скраппинга не будет, это использование публичного АПИ для конечно пользователя в виде PPC специалиста. Будем улучшать часть работы данного спеца, путем автоматизации некоторых процессов

Я бы сосредоточился на постановке самой задачи, а у вас не задача, а есть php/angular надо что-то сваять — технология вторична, она должна выбираться под задачу, а не наоборот. Как уже упомянули, вам возможно нужен не пхп, а shell скрипт в кроне, который в принципе для очередей и создан. Также стоит вопрос авторизации — мало кто в здравом уме даст вам контроль за гугл аккаунтом, даже в виде токена если вы не какая-то крупная контора.

Вы почувствуете, когда вашей системе чего-то не хватает. Сервер очередей будет решением если вам надо будет параллельно выполнять несколько задач в PHP для одного клиента, либо наоборот, сервер будет перегружен и некоторые задачи лучше поставить в очередь и выполнять по очереди.

С задержкой ответов сервер очередей никак не поможет а с отложенным задачами справится и обычный cron

Фреймворки не нужны, а теперь и серверы очередей ни к чему. От вас всё время узнаешь что-то новое.

Использовать нужно то что нужно а не то что модно или то что о чем прочитал в интернете. Зачем тут сервер очередей? Сервер очередей это дополнительное ПО в отличие от крона

Крон отлично работает когда нужно выполнять что-то общее для всего сервиса раз в несколько часов. Как вы будете использовать крон, если у вас есть UI, в котором авторизованный пользователь сам может добавлять/удалять задачи? Один скрипт запускать каждую минуту по крону и смотреть есть ли что делать? При некоторой тяжести задач и некотором количестве пользователей оно просто развалится. А у ТС ситуация как раз такая:

Кроме того каждый клиенты может поставить отложенную задачу

давайте тогда уже вместо крона фоновое выполнение на каждом сотом реквесте, чего уж мелочиться

Не з Дніпра, однак брав участь у подібному проекті. Мої думки:
1) ваш api буде мати попит, якщо буде більш доступним для розуміння, ніж першоджерело, наприклад:
1.1) документація краща ніж в гугл (сумніваюся, але можна постаратися)
1.2) результати будуть оброблені у більш human-readable форматі (таке цілком можливо)
2) ваша задача — слідкувати за deprecation dates і оновлювати своє api вчасно (до закриття поточної версії api гугла, вони часто люблять це робити зненацька і змінювати дату пост-фактум)
3) розклад запитів має право на життя, скажімо вашому клієнту достатньо виконувати запит лише один раз на добу в будні, а між ким це буде посередник — вирішувати вам, це більше філософське питання (поки нема технічних деталей вашого проекту).
На консультанта не тягну, та думки з цього приводу є і можна розвивати тему.

Підписатись на коментарі