Header Exchange¶
Header Exchange - самый сложный и гибкий способ маршрутизации сообщений в RabbitMQ. Данный тип exchange
отправляет сообщения
в очереди в соответствии с совпадением аргументов привязки этих очередей к exchange
с заголовками сообщений.
При этом, если очередь слушает несколько потребителей, сообщения все также будут распределяться между ними.
Пример¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
Объявление потребителей¶
Для начала мы объявили наш Fanout exchange и несколько очередей, которые будут его слушать:
8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Аргумент x-match
говорит о том, должны сопадать аргументы с заголовками сообщений полностью или частично.
Затем мы подписали несколько потребителей с помощью объявленных очередей на созданный нами exchange
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
Note
Обратите внимание, что handler1
и handler2
подписаны на один exchange
с помощью одной и той же очереди:
в рамках одного сервиса это не имеет смысла, так как сообщения будут приходить в эти обработчики поочередно.
Здесь мы эмулируем работу несколько потребителей и балансировку нагрузки между ними.
Распределение сообщений¶
Теперь распределение сообщений между этими потребителями будет выглядеть следующим образом:
await broker.publish(exchange=exch, headers={ "key": 1 }) # handlers: 1
Сообщение 1
будет отправлено в handler1
, т.к. он слушает очередь, заголовок key
которой, совпал с заголовком key
сообщения
await broker.publish(exchange=exch, headers={ "key": 1 }) # handlers: 2
Сообщение 2
будет отправлено в handler2
, т.к. он слушает exchange
с помощью той же очереди, но handler1
занят
await broker.publish(exchange=exch, headers={ "key": 1 }) # handlers: 1
Сообщение 3
снова будет отправлено в handler1
, т.к. он освободился на данный момент
await broker.publish(exchange=exch, headers={ "key": 2 }) # handlers: 3
Сообщение 4
будет отправлено в handler3
, т.к. он слушает очередь, заголовок key
которой, совпал с заголовком key
сообщения
await broker.publish(exchange=exch, headers={ "key2": 2 }) # handlers: 3
Сообщение 5
будет отправлено в handler3
, т.к. он слушает очередь, заголовок key2
которой, совпал с заголовком key2
сообщения
await broker.publish(exchange=exch, headers={ "key": 2, # handlers: 3, 4
"key2": 2 })
Сообщение 6
будет отправлено в handler3
и handler4
, т.к. заголовки сообщений полностью совпали с ключами очередей
Note
При отправке сообщений в Header exchange нет смысл указывать аргументы queue
или routing_key
, т.к. они будут проигнорированы
Warning
Для невероятно сложных маршрутов вы можете использовать возможность подписывать exchange
на другой exchange
с указанием ключа маршрутизации. В таком случае действуют все те же правила, что и для очередей, подписанных на exchange
. Отличие только в том, что подписанный exchange
может дальше распределять сообщения в соответствии со своими правилами.
Так, например, вы можете совместить Topic и Header типы.