Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Партиции воркеров и порядок
Одна подписка читает одну очередь через один канал, а workers(n, by_key) раскладывает её
доставки по партициям воркеров, выбирая их по заголовку.
Схема текстом
- Очередь orders один потребитель этого сервиса → Канал подписки окно предвыборки неподтверждённых доставок: передаются
- Канал подписки окно предвыборки неподтверждённых доставок → Поток LapinSubscriber по одной доставке
- Поток LapinSubscriber по одной доставке → workers(2, by_key) партиция = хеш заголовка amqp-partition-key: по одной
- workers(2, by_key) партиция = хеш заголовка amqp-partition-key → Партиция воркеров 1 ключи a и c, каждый по порядку
- workers(2, by_key) партиция = хеш заголовка amqp-partition-key → Партиция воркеров 2 ключ b, по порядку
- На сервере: обменник consistent-hash делит ключи между очередями, у каждой своя подписка
Поток подписки выдаёт по одной доставке в том порядке, в каком их передала очередь. Без workers
один цикл вызывает обработчик для каждой доставки по очереди, поэтому порядок очереди сохраняется,
и ничего не выполняется параллельно. Сколько доставок тем временем ждёт в сервисе, определяет окно
предвыборки.
workers(n, by_key) запускает n партиций воркеров. Доставка попадает в ту партицию воркеров, на
которую указывает хеш её ключа, а партиция воркеров выполняет свои доставки по порядку. Ключ - это
заголовок amqp-partition-key, который задаёт
производитель. AMQP его не читает: это соглашение между производителем и этим крейтом. У доставки
без этого заголовка нет ключа, и такие доставки по кругу распределяются по партициям воркеров.
Партициям воркеров нужно окно шире одной доставки. При предвыборке 1 очередь передаёт следующую доставку только после подтверждения предыдущей, и партиции воркеров работают по очереди.
Партиция воркеров сохраняет порядок внутри одного потребителя. Два экземпляра сервиса на одной
очереди - это два конкурирующих потребителя, и очередь распределяет доставки одного ключа между
обоими. Режим единственного активного потребителя RabbitMQ (x-single-active-consumer) - аргумент
очереди, который задаётся через argument. С ним очередь в
каждый момент читает только один потребитель.
Обменник consistent-hash переносит ту же идею на сервер. Он раскладывает ключи маршрутизации по нескольким очередям, и у каждой очереди своя подписка. В штатной работе один ключ попадает в одну очередь, поэтому его порядок сохраняется между экземплярами, пока у каждой очереди один потребитель.
Обработчик пакетов берёт то, что очередь уже передала, до размера, заданного в точке монтирования, поэтому пакет часто меньше этого размера.