Перейти к основному содержимому
Нормативная версия документации - английская

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

Партиции воркеров и порядок

Одна подписка читает одну очередь через один канал, а workers(n, by_key) раскладывает её доставки по партициям воркеров, выбирая их по заголовку.

Диспетчеризация одной подписки: очередь, канал подписки, один поток и две партиции воркеров по ключу amqp-partition-keyОчередь ordersодин потребитель этого сервисаКанал подпискиокно предвыборки неподтверждённых доставокПоток LapinSubscriberпо одной доставкеworkers(2, by_key)партиция = хеш заголовка amqp-partition-keyПартиция воркеров 1ключи a и c,каждый по порядкуПартиция воркеров 2ключ b, по порядкуНа сервере: обменник consistent-hash делитключи между очередями, у каждой своя подписка
Схема текстом
  1. Очередь orders один потребитель этого сервиса → Канал подписки окно предвыборки неподтверждённых доставок: передаются
  2. Канал подписки окно предвыборки неподтверждённых доставок → Поток LapinSubscriber по одной доставке
  3. Поток LapinSubscriber по одной доставке → workers(2, by_key) партиция = хеш заголовка amqp-partition-key: по одной
  4. workers(2, by_key) партиция = хеш заголовка amqp-partition-key → Партиция воркеров 1 ключи a и c, каждый по порядку
  5. workers(2, by_key) партиция = хеш заголовка amqp-partition-key → Партиция воркеров 2 ключ b, по порядку
  6. На сервере: обменник consistent-hash делит ключи между очередями, у каждой своя подписка

Поток подписки выдаёт по одной доставке в том порядке, в каком их передала очередь. Без workers один цикл вызывает обработчик для каждой доставки по очереди, поэтому порядок очереди сохраняется, и ничего не выполняется параллельно. Сколько доставок тем временем ждёт в сервисе, определяет окно предвыборки.

workers(n, by_key) запускает n партиций воркеров. Доставка попадает в ту партицию воркеров, на которую указывает хеш её ключа, а партиция воркеров выполняет свои доставки по порядку. Ключ - это заголовок amqp-partition-key, который задаёт производитель. AMQP его не читает: это соглашение между производителем и этим крейтом. У доставки без этого заголовка нет ключа, и такие доставки по кругу распределяются по партициям воркеров.

Партициям воркеров нужно окно шире одной доставки. При предвыборке 1 очередь передаёт следующую доставку только после подтверждения предыдущей, и партиции воркеров работают по очереди.

Партиция воркеров сохраняет порядок внутри одного потребителя. Два экземпляра сервиса на одной очереди - это два конкурирующих потребителя, и очередь распределяет доставки одного ключа между обоими. Режим единственного активного потребителя RabbitMQ (x-single-active-consumer) - аргумент очереди, который задаётся через argument. С ним очередь в каждый момент читает только один потребитель.

Обменник consistent-hash переносит ту же идею на сервер. Он раскладывает ключи маршрутизации по нескольким очередям, и у каждой очереди своя подписка. В штатной работе один ключ попадает в одну очередь, поэтому его порядок сохраняется между экземплярами, пока у каждой очереди один потребитель.

Обработчик пакетов берёт то, что очередь уже передала, до размера, заданного в точке монтирования, поэтому пакет часто меньше этого размера.