Глава 3. Экскурс вглубь свойств сообщения
Содержание
- Глава 3. Экскурс вглубь свойств сообщения
- Надлежащее использование свойств
- Создание контракта явного сообщения с content-type
- Уменьшение размера сообщения при помощи gzip и content-encoding
- Ссылочные сообщения с применением message-id и correlation-id
- Установка даты порождения: свойство timestamp
- Автоматическое истечение срока сообщения
- Балансировка скорости и безопасности с помощью delivery-mode
- Удостоверение происхождения сообщения через app-id и user-id
- Определение особенностей сообщения свойством типа сообщения
- Применение reply-to для динамических рабочих потоков
- Индивидуализация свойств при помощи атрибутов заголовка
- Приоритеты атрибутов
- Атрибуты, которые вы не можете использовать: cluster-id/reserved
- Выводы
Эта глава рассматривает
-
Свойства сообщение и их воздействие на доставку сообщений
-
Применение свойств сообщения для создания некоторого контракта между издателем и потребителем
В Главе 1 я подробно рассмотрел как я настраиваю расцепленных участников событий регистрации с записями в базу данных, которые вызывали задержки для участников регистрации в каком- то веб сайте. Основные преимущества такого подхода быстро стали ясными всей нашей инженерной организации и использование не жёстко связанной архитектуры для записей в базу данных возымело свою собственную жизнь. Со временем мы начали применять такую архитектуру в новых разрабатываемых нами приложениях. Со временем мы начали применять эту новую архитектуру в своих новых разрабатываемых приложениях. Мы больше не занимались обработкой событий регистраций участников, мы применяли эту архитектуру для удаления учётных записей, выработки сообщений электронной почты и любого прикладного события, которое может осуществляться асинхронно. События публиковались через имевшуюся общую шину обмена сообщениями для потребляющих их приложений, причём каждая из них исполняет свою собственную уникальную задачу. Поначалу мы слабо задавались вопросом о том что же именно содержится в данном сообщении и том как оно форматируется, однако вскоре стало очевидным, что такая стандартизация необходима.
При различных типах сообщений и отсутствии стандартизации формата сообщений становится трудно предсказывать как некий определённый тип сообщений должен упорядочиваться и какие данные должны содержать определённые типа сообщений. Разработчики должны публиковать сообщения в некоем формате, который имеет смысл для их приложения и их применения самого по себе. Хотя они и выполнили свои собственные задачи, такой образ мышления был близоруким. Мы стали замечать что сообщения могут применяться вновь и вновь во множестве приложений и произвольные решения о формате становятся проблематичными. Стремясь облегчить растущую головную боль вокруг этих проблем мы уделяли больше внимания описанию отправляемого сообщения как в документации, так и как часть самого по себе сообщения.
Для обеспечения согласованного метода для самостоятельного описания наших сообщений мы рассмотрели Basic.Properties
,
некую структуру данных AMQP, которая передаётся совместно с каждым сообщением, публикуемым через AMQP в RabbitMQ. Применение
Basic.Properties
открывает имеющиеся двери для более интеллектуальных потребителей - приложения потребителей,
которые могут автоматически преобразовывать получаемые сообщения, удостоверять само происхождение некоторого сообщения и его тип перед обработкой, а также
много чего ещё. В данной главе мы рассмотрим Basic.Properties
вглубь, обсуждая каждое его свойство и для чего
оно предназначено.
Как вы помните по Главе 2, при публикации вами сообщения в RabbitMQ ваше сообщение составляется
из трёх типов кадров нижнего уровня согласно спецификации AMQP: кадра метода Basic.Publish
, кадра заголовка
содержимого и кадра тела. Эти три типа кадров работают сообща в последовательности чтобы направить ваши сообщения по их назначению и гарантировать
их целостность после доставки (Рисунок 3-1).
Все содержащиеся в кадре заголовка свойства сообщения являются предварительно определённым набором значений, определяемых структурой данных
Basic.Properties
(Рисунок 3-2). Некоторые свойства,
такие как delivery-mode
имеют хорошо определённые значения в спецификации AMQP, в то время как другие, например
type
, не имеют точного определения.
В некоторых случаях RabbitMQ применяет чётко определённые свойства для реализации определённого поведения в зависимости от самого сообщения. Неким
примером такого использования может служить упомянутое ранее свойство delivery-mode
. Значение свойства
delivery-mode
сообщит RabbirMQ позволено ли ему сохранять данное сообщение в памяти при помещении этого
сообщения в некую очередь или ему требуется вначале сохранить данное сообщение на диск.
Совет | |
---|---|
Хотя для описания вашего сообщения рекомендуется применять свойства сообщений, вам следует быть уверенным, что все необходимые для потребляющих сообщения приложений содержатся в самом теле сообщения. Если, в конце концов, вы пожелаете состыковывать протоколы, например, MQTT с RabbitMQ, вы хотите быть уверенным, что ваши сообщения не теряют своего смысла когда не доступна специфичная для AMQP семантика. |
Раз уж мы рассмотрели процесс стандартизации сообщений, эти свойства сообщения AMQP могут послужить полезной отправной точкой для определения и
переноса метаданных о некотором сообщении. такие метаданные, в свою очередь, позволяют своему читателю создавать строгие контракты между издателями и
потребителями. Многие из имеющихся атрибутов, начиная с content-type
и типа сообщения
(type
) вплоть до timestamp
и идентификатора приложения
(app-id
), доказали свою полезность не только для состоятельности в процессе разработки, но и при их использовании
в повседневной работе. Если коротко, применяя свойства сообщения вы можете создавать сообщения с самоопределением, аналогично тому как XML
рассматривается как разметка данных с самостоятельным определением.
В этой главе мы рассмотрим каждое из базовых свойств, выделенных в Рисунке 3-2:
-
Применение свойства
content-type
позволяет пользователю знать как интерпретировать само тело сообщения -
Использование
content-encoding
указывает что тело данного сообщения может быть сжато или закодировано неким особым образом -
Свойства
message-id
иcorrelation-id
уникально идентифицируют сообщения и отклики на сообщение, отслеживая данное сообщение в вашем рабочем потоке -
Усиление свойством
timestamp
уменьшает размер сообщения и создаёт некое каноническое определение того когда было создано сообщение -
Срок истечения времени жизни сообщения содержится в свойстве
expiration
-
Для того чтобы указать RabbitMQ записывать ли ваши сообщения в очереди её хранением на диске или в оперативной памяти применяется
delivery-mode
-
Использование
app-id
иuser-id
помогает выявлять имеющих проблемы издателей -
Применение свойства
type
определяет некий контракт с издателями и потребителями -
Маршрутизация откликов сообщений при реализации шаблона пользуется свойством
reply-to
. -
Свойства таблицы
headers
применяются для свободной формы определений свойств и маршрутизации RabbirMQ
Мы также затронем то, почему вы захотите избегать использования свойства priority
и что случится с вашим
свойством cluster-id
и почему вы не можете применять его.
Я рассмотрю все свойства в указанном в этом перечне порядке, но я также включу некую удобную таблицу в конце данной главы, перечисляющую каждое свойство в их алфавитном порядке совместно с их типом данных, указанием того используется ли оно неким брокером или приложением, а также инструкциями по его применению.
Замечание | |
---|---|
Когда я применяю термин "контракт" в отношении сообщения, я подразумеваю спецификации для его формата и содержимого сообщения. В программировании это термин часто применяется для описания предварительно определённой спецификации API, объектов и систем. Спецификации контракта часто содержат точную информацию о передаваемых и принимаемых данных, например, допустимый тип данных, их формат и все условия, которые должны быть применимы к ним. |
Как я быстро определил, очень просто найти новые способы применения публикации сообщений с помощью RabbitMQ. Наше первичное приложение потребителя было написано на Python, но в скором времени сообщения потреблялись приложениями, написанными на PHP, Java и C.
В том случае, когда сообщения не являются самостоятельно описывающимися относительно своего формата полезной нагрузки, ваши приложения с большей вероятностью подвержены поломкам по причине применения контрактов в неявном виде, которые по своей природе склонны к ошибочности. Применяя самостоятельное описание сообщений программисты и потребляющие приложения не нуждаются в догадках о том как разбирать свои полученные данные в сообщениях или даже если такой разбор невозможен.
Структура данных Basic.Properties
определяет свойство content-type
для транспортировки необходимого формата ваших данных в передаваемом теле сообщения
(Рисунок 3-3).
Как и в различных стандартных спецификациях HTTP, content-type
переправляет определяемый тип MIME тела
своего сообщения. Если ваше приложение отправляет упорядоченные в виде JSON значения данных, например, установив значение свойства
content-type
в application/json
, это позволяет ещё- не- разработанному
приложению инспектировать данный тип сообщения по его получению и корректным образом декодировать данное сообщение.
Размышления о самоописании сообщений и содержимом сообщений | |
---|---|
Широко применяются стандартные форматы упорядочения данных, такие как JSON, Msgpack (msgpack.org) или XML. Эти форматы позволяют создавать любое количество потребительских приложений практически на любом языке программирования. Поскольку данные самостоятельно себя описывают в этих форматах, более просто писать последующие потребительские приложения, причём их легче декодировать из провода вне вашего основного приложения. Кроме того, определяя конкретный формат упорядочения в передаваемом свойстве |
Если для своего потребительского кода вы применяете некую инфраструктуру, вы можете пожелать сделать его умным в отношении того что делать с
получаемыми сообщениями. При наличии такой инфраструктуры предварительной обработки поступающих сообщений прежде чем обработать их в своём
потребительском коде, тело сообщения может автоматически разбираться и загружаться в естественные структуры данных в вашем языке программирования.
Например, в Python ваша инфраструктура может определять получаемый тип сообщения в его заголовке content-type
и,
применяя эту информацию, она может выполнять автоматический разбор тела сообщения и помещать содержимое в dict
,
list
или иной естественный тип данных. Это в конечном итоге снизит сложность вашего кода в вашем потребительском
приложении.
Отправляемые через AMQP сообщения по умолчанию не сжимаются. Это может быть проблематично с чрезмерно подробной разметкой, такой как XML, или даже с большими сообщениями, использующими менее интенсивно разбиваемые на поля форматы, такие как JSON или YAML. Ваши издатели могут сжимать сообщения до их публикации и распаковывать их при получении, подобно тому, как веб- страницы могут быть сжаты на сервере с помощью gzip, а браузер может распаковывать их на лету до построения изображения.
Чтобы обозначить этот процесс в явном виде AMQP определяет свойство content-encoding
(Рисунок 3-4).
Рисунок 3-4
Свойство
content-encoding
указывает применяется ли особенное кодирование в самом теле сообщения.
Теперь более предпочтительно изменить имеющийся контракт данного опубликованного и потреблённого в производстве сообщения, тем самым минимизировав любые
потенциальные эффекты имеющегося изначально кода. Однако, если размер сообщения воздействует на общую производительность и стабильность, его заголовок
content-encoding
позволит вашим потребителям заранее квалифицировать сообщения, гарантируя что они смогут
декодироваться из какого бы то ни было формата тела данного отосланного сообщения.
Замечание | |
---|---|
Не путайте |
Чтобы провести параллель, MIME язык разметки электронной почты применяет поле content-encoding
для указания определённой кодировки в каждой из своих различных частей данного электронного письма. В электронном письме наиболее применяемыми
типами являются Base64 и Quoted-Printable. Кодирование Base64 применяется для гарантии того, что передаваемые двоичные данные в этом сообщении не
нарушат протокол SMTP, содержащий только текст. Например, если вы создаёте некое сообщение электронного письма на основании HTTP со встроенными
изображениями, эти встроенные изображения скорее всего будут закодированы в Base64.
В отличии от SMTP, однако, AMQP является бинарным протоколом. Всё содержимое в теле его сообщения передаётся так, как если бы оно не было закодировано или преобразовывалось в соответствующих процессах упорядочения (marshaling) и разборки (remarshaling). Вне зависимости от формата любое содержимое может быть передано без рассмотрения нарушений данного протокола.
Усиление применимости потребительских инфраструктур | |
---|---|
Если вы применяете некую общую схему для создания своего потребительского кода, она может применять свойство
Мы обсудим общие потребительские схем более подробно в Главе 5. |
Совмещение свойства content-encoding
со свойством content-type
придаёт дополнительную мощность потребляющему приложению в обработке некоторого подробного контракта его издателей. Это позволяет вам создавать
непробиваемый в последующем код, упрочняя его по отношению к неожиданным ошибкам, вызываемыми изменениями в формате сообщений. Например, в некий
момент жизненного цикла вашего приложения вы можете обнаружить, что сжатие bzip2 лучше подходит для содержимого ваших сообщений. Если ваш код в
потребляющем приложении опрашивает свойство content-encoding
, он может затем отвергать сообщения, которые
не может декодировать. Те потребители, которые знают что они могут развёртывать только при помощи zlib или deflate будут отвергать новые сообщения,
сжатые bzip2, оставляя их в очереди для прочих потребляющих приложений, которые способны выполнять развёртывание сообщений bzip2.
В спецификации AMQP message-id
и correlation-id
определены
"для приложений пользователя" и не имеют формально определяемого поведения
(Рисунок 3-5).
Это означает, что то что касается самой спецификации, вы можете применять их в любых целях по своему усмотрению. Оба поля допускают до 255 байт закодированных
UTF-8 данных и хранят несжатые значения, встраиваемые в структуру данных Basic.Properties
.
Рисунок 3-5
Свойства
message-id
и correlation-id
могут применяться для отслеживания персональных сообщений и сообщений откликов
по мере их прохождения в вашей системе.
Некоторые типы сообщений, в примеру, такие как события регистрации, скорее всего не нуждаются в связанных с ними уникальных идентификаторах сообщения,
однако легко представить типы сообщений, которым они бы не помешали, скажем, ордеры продажи или запросы на сопровождение. Свойство
message-id
позволяет данному сообщению переносить данные в своём заголовке, которые уникальным образом
идентифицируют его в потоке через различные компоненты в слабо связанной системе.
Хотя и формальное определение для correlation-id
в имеющейся спецификации AMQP отсутствует, оно используется
для указания того, что данное сообщение является откликом на другое сообщение, перенося значение
message-id
того сообщения. Другим вариантом является его применение для переноса некоего идентификатора транзакции или иных аналогичных данных, которые могут
относиться к определённому сообщению.
Одним из наиболее полезных полей в Basic.Properties
является свойство timestamp
(Рисунок 3-6).
Наряду с message-id
и correlation-id
timestamp
определяется как "используемый для приложения". Даже если ваше сообщение не применяет его,
значение свойства timestamp
очень полезно когда вы пробуете диагностировать любой вид неожиданного поведения
в своём потоке сообщений, проходящем через RabbitMQ. Используя значение свойства timestamp
для указания
того, когда приложение было создано, потребители могут калибровать производительность доставки сообщения.
Рисунок 3-6
Свойство
timestamp
может переносить некой значение эпохи для определения того, когда это сообщение было создано.
Существует ли соглашение об уровне обслуживания (SLA, service level agreement), которое должны выполнять ваши процессы? Вычисляя
timestamp
в свойствах сообщения, ваши потребительские приложения могут принимать решение, будут ли они обрабатывать
сообщение, отбрасывать его или даже публиковать предупреждающее сообщение в приложении мониторинга, чтобы кто-то знал, что возраст сообщения превышает
желаемое значение.
Значение timestamp
отправляется как эпоха Unix или timestamp
на основе целого значения, указывающее численная величина, исчисляемая с полуночи 1 января 1070. Например, полночь 2 февраля 2002 должна быть представлена
как целочисленное значение 1329696000. Будучи закодированным как целочисленная величина, timestamp
занимает
всего лишь 8 байт в объёме вашего сообщения. К сожалению, для значения timestamp
нет контекста временной
зоны, поэтому предлагается применять UTC или иную подходящую зону времени по всем вашим сообщениям. Устанавливая стандарт часового пояса, вы избегаете
любых проблем в будущем, которые могут возникнуть как результате того, что ваши сообщения перемещаются по часовым поясам географически распределённых
брокеров RabbitMQ.
Свойство expiration
сообщает RabbitMQ когда стоит отвергать сообщение если оно не было потреблено. Хотя
свойство expiration
(Рисунок 3-7)
имеется в обеих версиях AMQP, и в 0-8, и в 0-9-1, оно не поддерживалось в RabbitMQ вплоть
до выпуска версии 3.0. Кроме того, само определение свойства expiration
слегка странное; оно предписывает
"применяться для реализации; никакого формального поведения", что подразумевает, что RabbitMQ может тем не менее реализовать его по своему
усмотрению. Одна завершающая странность состоит в том, что оно определено как короткая строка, допускающая до 255 символов, в то время как другое
представляющее единицы времени свойство, timestamp
, является целочисленным значением.
Рисунок 3-7
Для использования свойства
expiration
в rabbitMQ, установите необходимое строковое значение для мременного штампа Unix,
обозначающее максимальное значение, для которого данное сообщение всё ещё остаётся в силе.
Из- за имеющейся неопределённости в спецификации, применяемое значение expiration
с большой вероятностью
может иметь различные реализации при применении различных брокеров обмена сообщениями или даже различные версии одного и того же брокера обмена
сообщениями. Для автоматического исетчения срока действия сообщений при использовании в RabbitMQ рассматриваемого свойства
expiration
оно должно содержать некую эпоху Unix, или временной штамп на основе целочисленного значения, но
хранить его в виде строки. Вместо хранения некоторого временного штампа в формате ISO-8601, например,
"2002-02-20T00:00:00-00
", вы должны установить его строковое значение в эквивалент, представленный как
"1329696000
".
При применении данного свойства expiration
, если некое сообщение публикуется в имеющемся сервере с уже
истекшим штампом времени, такое сообщение не будет перенаправляться ни в какие очереди, а вместо этого будет отвергаться.
Также стоит отметить, что у RabbitMQ имеются и прочие средства управления сроком истечения времени действия ваших сообщений только при определённых
обстоятельствах. При определении некоей очереди вы можете передать ей аргумент x-message-ttl
одновременно
с её определением. Данное значение также должно быть неким временным штампом эпохи Unix, однако оно применяет точность в миллисекундах
(value*1000
) в качестве некоторого целого значения. Данное значение инструктирует свою очередь автоматически
отвергать сообщения, если указанное время истекло. Этот аргумент очереди x-message-ttl
и параметры его
измерения при его использовании будут более подробно обсуждены в Главе 5.
Свойство delivery-mode
является байтовым полем, которое указывает использующему его брокеру обмена сообщениями
что вы желаете оставить данное сообщение на диске прежде чем оно будет доставлено любому ожидающему его потребителю
(Рисунок 3-8).
В RabbitMQ оставление (persisting) некоторого сообщения означает, что оно будет оставаться в данной очереди пока не будет потреблено, даже в случае
перезапуска данного сервера RabbitMQ. Данное свойство delivery-mode
имеет два возможных значения:
1
для не оставляемых сообщений и 2
для оставляемых сообщений.
Рисунок 3-8
Свойство
delivery-mode
указывает RabbitMQ должен ли он сохранять получаемое сообщение на диск при размещении его в очереди, или
он может оставлять его только в оперативной памяти.
Замечание | |
---|---|
При первом изучении различных терминов и установок в RabbitMQ, оставление (persistence) может зачастую путаться с с установкой
|
Как иллюстрирует Рисунке 3-9, определение вашего сообщения как не оставляемого позволит RabbitMQ применять очереди, располагаемые только в оперативной памяти.
Так как ввод/ вывод в оперативной памяти быстрее дискового ввода/ вывода, определение delivery-mode
равным
1 будет осуществлять доставку ваших сообщений с настолько малой латентностью, насколько она возможна. В моём случае с регистрацией веб приложения
данный выбор режима доставки может быть более простым, нежели в прочих случаях. Хотя и желательно не терять никакие события регистрации в случае падения
какого- то сервера RabbitMQ, как правило, это не строгое требование. В случае когда данные события регистрации участника утрачены, вряд ли пострадает
сам бизнес. В данном случае мы применяем delivery-mode:1
. Однако, если вы применяете RabbitMQ для публикации
данных финансовой транзакции, а архитектура вашего приложения сосредоточена на обеспечении доставки вместо пропускной способности обмена сообщения,
вы можете разрешить оставление определив delivery-mode:2
. как показывает
Рисунок 3-10,
при определении режима доставки равным 2, сообщения оставляются в очереди, базирующейся на диске.
Хотя это предоставляет некую гарантию того, что сообщения не будут утрачены в случае краха брокера обмена сообщениями, это влечёт за собой потенциальные
трудности с производительностью и масштабированием. Свойство delivery-mode
имеет настолько значительное воздействие
на доставку и производительность, что оно более подробно рассматривается в Главе 4.
Свойства app-id
и user-id
предоставляют другой уровень информации
о сообщении и имеют множество потенциальных применений
Рисунок 3-11.
Как и в случае прочих свойств, которые могут применяться для специфического поведения контракта в данном сообщении, эти два свойства способны
переносить информацию, которую ваше потребительское приложение может проверять перед обработкой.
Рисунок 3-11
Свойства
app-id
и user-id
являются последними в имеющихся значениях Basic.Properties
и они
могут применяться для идентификации своего источника сообщения.
Свойство app-id
определяется в существующей спецификации AMQP как "короткая строка", допускающая
до 255 символов UTF-8. Если ваше приложение имеет сосредоточенную вокруг API архитектуру с поддержкой версий, вы можете применять свойство
app-id
для переправки той специфичности API и версии, которая применялась при создании данного сообщения.
В качестве метода усиления контракта между издателем и потребителем, опрос свойства app-id
перед
тем как выполнить обработку позволит вашему приложению отвергнуть полученное сообщение если оно происходит от неизвестного или не поддерживаемого
источника.
Другое возможное применение для app-id
состоит в сборе статистических данных. Например, если вы применяете
сообщения для переправки событий регистрации, вы можете установить данное свойство app-id
для платформы и
версии того приложения, которое переключила это событие регистрации. В среде, в которой вы можете иметь приложения на базе веб интерфейса, настольные
системы и мобильных клиентов, это может стать великолепным способом прозрачным образом как исполнять некий контракт, так и выделять данные для
отслеживания регистраций в соответствии с платформой, причём без какой бы то ни было инспекции самого тела сообщения. Это в особенности удобно если вы
желаете иметь потребителей с единственной целью допускали сбор статистики потребителей, которые ожидают те же самые сообщения что и ваш потребитель,
обрабатывающий регистрацию. Предоставляя такое свойство app-id
сбор статистики потребителем не требует разбора
или декодирования самого тела сообщения.
Совет | |
---|---|
Когда вы пытаетесь отслеживать непослушные сообщения в своих очередях, принуждение к применению
|
При использовании аутентификации пользователя может показаться очевидным применение свойства user-id
для указания того пользователя, который зарегистрировался, но в большинстве случаев это нецелесообразно. RabbitMQ проверяет все сообщения опубликованные
со значением в имеющемся свойстве user-id
для того пользователя RabbitMQ, который опубликовал это сообщение и если
эти два значения не совпадают, данное сообщение отклоняется. Например, если ваше приложение прошло аутентификацию в RabbitMQ с пользователем
"www", а его свойство user-id
установлено в значение "linus", данное сообщение будет
отвергнуто.
Конечно,если ваше приложение является чем- то навроде комнаты чата или экземпляра службы сообщения, вы вполне можете пожелать какого- то пользователя для
каждого пользователя вашего приложения и вы на самом деле пожелаете применять
user-id
для идентификации фактического входа пользователя в ваше приложение.
Версия 0-9-1 спецификации AMQP определило свойство type
в Basic.Properties
как "название типа сообщения" сообщив, что оно служит для применения в приложении и не имеет формализованного определения
Рисунок 3-12.
Хотя имеющееся значение routing-key
в комбинации с exchange
зачастую
может переносить столько информации о данном сообщении, сколько ему требуется для определения своего содержимого, данное свойство
type
добавляет иной инструмент вашему приложению, который способен определять как обрабатывать сообщение.
Рисунок 3-12
Свойство
type
является значением строки в свободном виде, которое может применяться для определения заданного типа сообщения.
Когда самостоятельно определяющиеся форматы упорядочения не являются достаточно быстрыми | |
---|---|
Свойство При попытке создать самостоятельно описывающие сообщения AMQP, которые допускают некий принудительный контракт между издателем и потребителем, полезная нагрузка
сообщения, которая не является с самостоятельным описанием, требует заблаговременной разборки полезной нагрузки сообщения чтобы определить, всё ли хорошо с
обрабатываемым потребителем сообщением. В этом случае свойство |
В моём примере публикации событий регистрации участника, когда наступает время сохранить это событие в хранилище данных, мы считаем полезным
переносить значение типа сообщения вместе с самим сообщением. Для подготовки этих событий к сохранению в хранилище данных они вначале должны быть
запомнены во временном местоположении, а затем некий пакетный процесс считывает их и сохраняет их уже в необходимом хранилище. Поскольку это очень
распространённый процесс, отдельный потребитель выполняет все фазы выделения общего процесса ETL (extract-transform-load - выделить- преобразовать-
загрузить) с помощью какой- то общей очереди для обработки всех имеющихся сообщений. Такой потребитель очереди ETL обрабатывает множество типов сообщений и
использует имеющееся свойство type
для принятия решения о том, в какой системе, таблице или кластере
сохранять выделяемые данные.
Замечание | |
---|---|
Обработка ETL является некоторой стандартной практикой при которой выделяются данные OLTP и в конечном итоге загружаются в некое хранилище данных с целью выработки отчётов. Если вы желаете подробнее ознакомиться с обработкой ETL, в Wikipedia имеется очень хорошая статья с описанием каждого этапа, производительности ETL, обычно возникающих проблем и связанных с этим предметов. . |
В запутанном и кратком определении в спецификации AMQP свойство span class="term">reply-to
не имеет формально определяемого поведения и также отдаётся на откуп для использования приложением
(Рисунок 3-13).
В отличии от упоминавшихся ранее свойств, оно имеет предупреждение: reply-to
может применяться
для обозначения частного отклика очереди в виде реплик на сообщение. Хотя точное определение частного отклика очереди и не постулируется в
спецификации AMQP, данное свойство запросто может переносить либо определённое имя очереди, либо ключ маршрутизации в качестве ответа в
некотором обмене через который данное сообщение первоначально было опубликовано.
Рисунок 3-13
Свойство
reply-to
не имеет формального определения, однако может нести некий ключ маршрутизации или название очереди, которые
могут применяться для откликов на данное сообщение.
Предостережение | |
---|---|
В версии 0-9-1 спецификации AMQP имеется некое предупреждение для |
Свойство headers
является таблицей ключ/ значение, которое допускает произвольные, определяемые пользователем
ключи и значения
(Рисунок 3-14).
Ключи могут быть строками ASCII или Unicode, которые имеют максимальную длину в 255 символов. Значения могут быть любым допустимым типом значения
AMQP.
Рисунок 3-14
Свойство
headers
делает возможными произвольные пары ключ/ значение в имеющихся свойствах сообщения.
В отличии от прочих свойств, данное свойство headers
позволяет вам добавлять любые данные, которые вы пожелаете
в данный заголовок таблицы. Оно также имеет и иное уникальное свойство: RabbitMQ способен перенаправлять сообщения но основе тех значений, которыми
заполнен такой headers
таблицы вместо того чтобы полагаться на имеющийся ключ маршрутизации. Маршрутизация сообщений
через данное свойство headers
рассматривается в Главе 6.
В RabbitMQ 3.5.0 было реализовано поле priority
как это определено в спецификации AMQP.
Оно определяется как некое целое с возможными значениями от 0 до 9 подлежащими к применению для установки приоритета сообщения в очереди.
Согласно спецификации, если публикуется некое сообщение с приоритетом 9, а вслед за ним публикуется сообщение с приоритетом 0, вновь подключающийся
потребитель получит тот сообщение, которое имеет приоритет 0 прежде чем сообщение с приоритетом 9. Занимательно, что RabbitMQ реализует это поле
priority
как байтовое значение без знака, поэтому приоритетами могут быть значения от 0 до 266, однако для
сопровождения возможности взаимодействия сетевых сред в соответствии со спецификацией применяемое значение приоритета следует ограничивать в пределах
от 0 до 9
См. Рисунок 3-15.
Рисунок 3-15
Свойство
priority
может применяться для назначения приоритета в очередях для имеющихся сообщений.
Имеется ещё одно свойство, которому стоит уделит ваше внимание, причём с единственной целью чтобы дать вам знать что вы не можете его применять.
Скорее всего вы уже заметили перечёркнутое свойство cluster-id
на всех предыдущих рисунках
(Рисунок 3-16).
Рисунок 3-16
Свойство
cluster-id
было переименовано как зарезервированное в AMQP 0-9-1 и его не следует применять.
Данное свойство cluster-id
было определено в AMQP 0-8, однако впоследствии было удалено. и RabbitMQ никогда не
реализовывал никакой вид поведения относительно него. AMQP 0-9-1 переименовал его в reserved
и
постулировал, что оно должно оставаться пустым. Хотя RabbitMQ в настоящее время не заставляет выполнять требование спецификации на то, чтобы оно было
пустым, вам лучше избегать его совсем.
Применяя свойство Basic.Properties
, ваша архитектура сообщений может создавать контракты между издателями и
потребителями со строгим поведением. Кроме того, вы будете способны обеспечить в будущем свои сообщения интеграцией в проектах, которые вы возможно и
не рассматривали в своих первичных приложениях и спецификациях сообщений.
Таблица 3-1 предоставляет быстрый обзор этих свойств. Вы можете вернуться и применить её в качестве справки для выяснения правильного применения свойств в своёи приложении.
Свойство | Тип | Для применения в | Предложение или предписание применения |
---|---|---|---|
|
|
Приложение |
Полезно для задания приложения, опубликовавшего данные сообщения |
|
|
Приложение |
Определяет кодируется ли тело сообщения особым образом, например, с помощью zlib, deflate или Base64. |
|
|
Приложение |
Определяет тип данного сообщения с использованием типа MIME. |
|
|
Приложение |
Если данное сообщение ссылается на некое другое сообщение или уникально указываемое им,
|
|
|
RabbitMQ |
Значение |
|
|
RabbitMQ |
Значение штампа времени эпохи Unix в виде текстовой строки, которое указывает когда истекает срок действия данного сообщения. |
|
|
Оба |
Таблица ключ/ значение в произвольном виде, которую вы можете применять для добавления дополнительных метаданных о своём сообщении; RabbitMQ, может выполнять маршрутизацию на основании их при вашем желании на то. |
|
|
Приложение |
Уникальный идентификатор, такой как UUID, который ваше приложение может применять для указания данного сообщения. |
|
|
RabbitMQ |
Свойство для определения значения приоритета в очередях. |
|
|
Приложение |
Значение эпохи или временного штампа Unix, которое может применяться для указания того, когда это сообщение было создано. |
|
|
Приложение |
Текстовая строка, которую ваше приложение иожет применять для описания типа самого сообщения или его полезной нагрузки. |
|
|
Оба |
Строка в произвольном виде, которую, если она используется, RabbitMQ будет проверять для сопоставления с подключённым сообщением и удалять данное сообщение в случае несоответствия. |
Помимо применения свойств для самостоятельного описания сообщений, эти свойства могут переносить существенные метаданные о вашем сообщении, которые
позволят вам создавать изощрённые механизмы маршрутизации и транзакций без необходимости загрязнять само тело сообщения контекстной информацией,
принадлежащей данному сообщению. При вычислении данного сообщения для его доставки, RabbitMQ будет применять специфические свойства , такие как
delivery-mode
и таблицу headers
чтобы гарантировать что ваши сообщения
будут доставлены туда и таким образом как вы предписали. Однако эти значения являются всего лишь верхушкой айсберга, когда дело доходит до того, что
необходимо обеспечить пуленепробиваемую доставку.