Как в RabbitMQ, или без него, настроить классическую очередь?

Привет!
Продолжительное время думаю над архитектурой одного проекта, но столкнулся с тех. вопросами в плане реализации.

Описание: есть 100к компьютеров-клиентов, скажем, в 50-ти интернет-клубов по стране. После каждой сессии работы на этих компах, они должны соединяться для отправки отчёта с главным серверов №2, который в свою очередь соединяется с главным сервером №1, чтобы передать отчёт, полученный от клиента, получить ответ и передать снова серверу №2, а тот -- клиенту. Время на получение ответа клиентом от сервера №2 составляет 10 секунд, если за это время ответа не получено -- соединение разрывается.

Также существует 2 вида работы: онлайн и оффлайн.
Онлайн: всё работает в порядке классической очереди, каждый отчёт обрабатывается по дате. Клиент начал и завершил сессию -> открыл соединение с сервером №2 для отправки отчёта с ожиданием в 10 секунд -> сервер №2 получил и записал в очередь -> из очереди берутся отчёты и отправляются серверу №1 для проверки и записи -> сервер №1 получает и отправляет ответ серверу №2 -> сервер №2 отправляет ответ об успешном завершении операции клиенту, который ждёт 10 секунд.

Оффлайн: Бывает такое, что сервер №1 может отвалиться в любой момент. И тогда клиент не получает ответа в течение 10 секунд, то он говорит, что сейчас он работает в оффлайн режиме. Но всё так же продолжает отправлять отчёты серверу №2. Сервер №2 так же принимает отчёты, но записывает их уже в очередь-оффлайн, которая так же должна обработаться, как только заработает сервер №1. И другие отчёты, которые приходят от клиента, так же должны ожидать. Потому что сервер №1 принимает всё последовательно.

Вопрос: как правильно организовать такую архитектуру и на чём?
Пока я пришёл к использованию RabbitMQ и микросервисов. Но думаю, что это будет моветоном для каждого клиента (100к компов) создавать свою очередь, причём будем две очереди: онлайн и оффлайн. Онлайн не обработается, пока не закончится оффлайн очередь. Но для каждого компа всё должно обрабатываться последовательно, по дате: получается такая "классическая" Советская очередь. Но параллельно с несколькими компами: 100к компов обрабатывается параллельно, но отчёты с каждого из них -- последовательно. Исходя из подсчётов: 100к клиентов и на каждого 2 очереди = 100 * 2 = 200 очередей, по 2 очередей на каждый комп.

Как правильно тут поступить? Идеи, советы?
  • Вопрос задан
  • 922 просмотра
Пригласить эксперта
Ответы на вопрос 2
tumbler
@tumbler
бекенд-разработчик на python
из очереди берутся отчёты и отправляются серверу №1 для проверки и записи

Ага, вот это место, в котором решается, оффлайн сервер№1 или онлайн.

Потому что сервер №1 принимает всё последовательно

А это главное требование.

Вариант номер 1.
Одна общая очередь, один воркер. Если сервер №1 оффлайн, воркер просто останавливает свою работу до тех пор, пока сервер не вернется. Для текущего сообщения надо выполнить amqp reject, тогда оно вернется в начало очереди.
Порядок сообщений соблюден, но есть единая точка отказа, она же бутылочное горлышко производительности (впрочем, зависит от скорости обработки отчетов)

Вариант №2.
Одна общая очередь, много воркеров. Схема та же, сервер оффлайн - остановка обработки. Онлайн - возобновление. Узкое место по производительности и точка отказа исчезают, но два последовательных отчета от одного компьютера могут попасть одновременно на соседние воркеры, т.е. требование про "последовательно" может не выполняться.

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

Как-то так. Сходу придумать, как заставить несколько воркеров обрабатывать одну очередь с сохранением порядка сообщений я не придумал.
Ответ написан
@kttotto
пофиг на чем писать
Не совсем понятно, зачем очередь на каждом компьютере? По сути очередь нужна только на компьютере №2. Все клиенты отправляют на него отчет, отчеты кладутся в очередь, компьютер №1 забирает их из этой очереди. И очередь для того и нужна, чтобы не зависеть, в сети ли компьютер №1. Все сообщения будут лежать в очереди, пока первый их не заберет. Если в течении какого то времени сообщение не забрали, клиенту дается ответ, что первый не доступен и клиент через таймаут шлет очередное сообщение.

Каждый клиент имеет свой идентификатор, каждый отчет свой идентификатор и если в очереди оказалось несколько сообщений от одного клиента и с одним идентификатором отчета, то учитывается последний по дате. Ну в принципе и все.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы