[Расширенная дорога] Очередь сообщений — принцип RabbitMQ (2)

очередь сообщений

предисловие

Привет всем, я Нанджу. Прошло почти два года с тех пор, как я познакомился с java. За два года я прошел путь от супер-новичка, который даже не понимает несколько структур данных в java, до немного продвинутый младший Бай, многому научился. Чем больше знаний передается, тем они ценнее.За это время я обобщил (в том числе изучая и цитируя других воротил) некоторые ключевые моменты (самомышления) в моем обычном исследовании и интервью, надеясь принести вам некоторую помощь.

Это статья о промежуточном программном обеспечении для сообщений, если вы ее не читали, вы можете прочитать ее.

Нуждающиеся студенты могут добавить мой официальный аккаунт, последние статьи в будущем будут в нем впервые, или вы можете попросить у меня ментальную карту

1. Основные понятия

Благодаря изучению предыдущей главы мы уже знаем характеристики RabbitMQ, теперь немного вспомним:

  • Сам RabbitMQ относительно прост в установке и развертывании (один экземпляр/кластер),Низкий порог для начала работы, богатые функции, соответствует стандарту AMQP

  • Кластер RabbitMQЛегко масштабировать, вы можете добиться эффекта эластичного расширения и сокращения, увеличив или уменьшив количество экземпляров узлов в кластере в соответствии с фактическим объемом бизнес-доступа.

  • Промежуточное ПО очереди сообщений корпоративного уровня, проверенное большим количеством практических кейсов в производственной среде различных компаний отрасли,Обладает высокой надежностью

  • RabbitMQ предоставляетПростой в использовании пользовательский интерфейс, так что пользователи могут отслеживать и управлять многими аспектами брокера сообщений.Если сообщение является ненормальным, RabbitMQ предоставляетмеханизм отслеживания сообщений, пользователь может узнать, что произошло.

  • Поддержка сохранения сообщений, поддержка механизма подтверждения сообщений, гибкий механизм распределения задачи т. д., функция поддержки очень богата

  • выполнитьвысокая доступность, вы можете создать зеркало очереди на машине в кластере RabbitMQ, чтобы очередь по-прежнему была доступна в случае отказа какого-либо узла.

Но это только причина, по которой мы его используем.Чтобы действительно заставить RabbitMQ работать в нашей системе, нам нужно знать больше.

1. Сообщение

Сообщение является основой MQ, состоящей из заголовка сообщения и тела сообщения. Тело сообщения представляет собой информацию, передаваемую производителем потребителю, а заголовок сообщения состоит из ряда необязательных атрибутов, включая ключ маршрутизации (ключ маршрутизации), приоритет (приоритет по отношению к другим сообщениям), режим доставки (указать что сообщение может потребовать постоянного хранения) и т. д.

2. Издатель

Производитель сообщения также является клиентским приложением, которое публикует сообщение.

3. Обмен

Обмен, который получает сообщения, отправленные производителями, и направляет их в очереди на сервере.

4. Ключ маршрутизации

Ключ маршрутизации — это ключ для просмотра коммутатором и принятия решения о том, как распределить сообщение в очередь в соответствии с ключом.Можно сказать, что ключ маршрутизации является адресом назначения сообщения.

5. Привязка

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

** 6. Очередь**

Очередь сообщений, используемая для хранения сообщений до тех пор, пока они не будут отправлены потребителям. Это контейнер для сообщения и пункт назначения для сообщения. Сообщение может быть помещено в одну или несколько очередей. Сообщение было в очереди, ожидая, пока потребитель подключится к очереди, чтобы забрать его.

7. Подключение

TCP-соединение между RabbitMQ и сервером приложений

8. Канал

канал, независимый двунаправленный канал потока данных в мультиплексном соединении. Канал — это виртуальное соединение, установленное в реальном TCP-соединении.Команды AMQP отправляются через канал.Будь то публикация сообщения, подписка на очередь или получение сообщения, эти действия выполняются через канал. Поскольку установление и уничтожение TCP очень дорого обходится операционной системе, для повторного использования TCP-соединения вводится понятие канала.

9. Потребитель

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

10. Виртуальный хост

Виртуальный хост, представляющий набор обменов, очередей сообщений и связанных объектов. Виртуальные хосты — это отдельные серверные домены, использующие одну и ту же среду аутентификации и шифрования. Каждый виртуальный хост по сути представляет собой мини-версию сервера RabbitMQ со своими очередями, обменами, привязками и механизмами разрешений. vhost является основой концепции AMQP и должен быть указан во время подключения.

2. Процесс коммуникации

Поняв базовую структуру RabbitMQ, давайте объясним процесс коммуникации RabbitMQ с помощью рисунка:

Разве не прекрасно рисовать, и ты можешь сразу использовать то, чему научился раньше~

Анализ процесса:

  • 1. Производитель сообщений подключается к RabbitMQ Broker, создает соединение и открывает канал.
  • 2. Производитель объявляет тип коммутатора, имя, является ли он постоянным и т.д. (На самом деле это утверждение не очень точное, на самом деле большинство из них объявляются сначала на странице управления или на стороне потребителя).
  • 3. Производитель отправляет сообщение и указывает, является ли сообщение постоянным, а также другие атрибуты и ключи маршрутизации.
  • 4. После того, как биржа получает сообщение, она направляет его в очередь, которая соответствует текущей привязке биржи в соответствии с ключом маршрутизации.
  • 5. Потребитель слушает, чтобы начать бизнес-обработку после получения сообщения, а затем отправляет подтверждение, чтобы подтвердить, что сообщение было использовано (как вручную, так и автоматически).
  • 6. После получения подтверждения RabbitMQ Broker удаляет соответствующее сообщение из очереди.

3. Режим маршрутизации сообщений

Позаимствованные фотографии у босса

1. Прямой режим (Direct)

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

в этом режимеНет необходимости выполнять какие-либо операции привязки на Exchange.,Для передачи сообщений требуется «RoutingKey»., что можно просто понимать как имя очереди для отправки. ноЕсли имя очереди, указанное в RoutingKey, не существует на виртуальном хосте, сообщение будет отклонено..

2. Режим вещания (Fanout)

Разветвленные обмены не обрабатывают ключи маршрутизации, они просто привязывают очереди к обмену, и каждое сообщение, отправленное на обмен, перенаправляется во все очереди, связанные с этим обменом. Как и при широковещании подсети, узлы в каждой подсети получают копию сообщения. Таким образом, пересылка сообщений типа Fanout является самой быстрой.

режим трансляцииRoutingKey не требуется, просто заранее привяжите Exchange к очереди, Exchange может быть привязан к нескольким очередям, а очередь может быть привязана к нескольким Exchange. ноЕсли Exchange, получивший сообщение, не привязан к какой-либо очереди, сообщение будет отброшено.

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

3. Тема

Любое сообщение, отправленное в Topic Exchange, будет перенаправлено во все очереди, которым важна тема, указанная в RouteKey.

Каждая очередь имеет интересующую ее тему, и все сообщения имеют «заголовок» (ключ маршрутизации RoutingKey), и Exchange пересылает сообщение во все очереди, интересующая тема которых может смутно совпадать с RoutingKey.Для режима темы требуется RoutingKey, а также необходимо заранее связать Exchange и Queue.При привязке укажите тему, о которой заботится очередь.. Тематический режим имеет два ключевых слова # и *.

  • "#" указывает 0 или несколько ключевых слов, например "#.nanju.#" указывает, что очередь заботится обо всех сообщениях, связанных с nanju (сообщение, RoutingKey которого равно "asd.MQ.nanju.error", будет перенаправлено в очередь) ,
  • *Представляет ключевое сообщение, например "*.nanju.*"(Сообщение с RoutingKey "asd.nanju.error" будет перенаправлено в эту очередь, а "asd.MQ.nanju.error" - нет)

Аналогичным образом, если Exchange не находит очередь, соответствующую RoutingKey, сообщение отбрасывается.

4. Рабочий режим

1. Простой режим: один производитель, один потребитель

Процесс:

  • 1. Производитель помещает сообщение в очередь сообщений.
  • 2. Потребитель сообщения прослушивает очередь сообщений, и если в очереди есть сообщение, оно будет использовано. После того, как сообщение потребляется, оно автоматически удаляется из очереди (легко видеть, что сообщение не было правильно обработано потребителем и исчезло из очереди, что привело к потере сообщения)

Подходящая сцена:

  • простая система чата

2. Режим работы: один производитель, несколько потребителей, каждый потребитель получает уникальное сообщение

Процесс:

  • 1. Производитель помещает сообщение в очередь сообщений.
  • Потребители нескольких сообщений одновременно прослушивают содержимое очереди сообщений, и тот, кто получает его первым, несет ответственность за потребление сообщения (в случае высокой степени параллелизма определенное сообщение будет сгенерировано несколькими потребителями по умолчанию, а переключатель может быть установлен таким образом, чтобы сообщение могло быть использовано только несколькими потребителями (используется потребителем)

Подходящая сцена:

  • возьмите красный конверт
  • Случайно назначать задачи

3. Режим подписки: сообщения, отправленные одним производителем, будут получены несколькими потребителями.

Процесс:

  • 1. Производитель сообщения помещает сообщение в обмен
  • 2. Коммутатор публикует и подписывается на отправку сообщений во все очереди сообщений, а потребители соответствующих очередей сообщений получают сообщения для потребления.

Подходящая сцена:

  • Доставка почты
  • Подписка на сцену
  • Отправить смс

4. Режим маршрутизации: отправьте сообщение коммутатору и укажите ключ маршрутизации.Потребители должны указать ключ маршрутизации при привязке очереди к коммутатору.

Процесс:

  • 1. Производитель сообщения отправляет сообщение на биржу
  • 2. В соответствии с ключом маршрутизации коммутатор может сопоставить только очередь сообщений, соответствующую ключу маршрутизации, и соответствующие потребители могут потреблять сообщения;

Режим маршрутизации аналогичен режиму подписки, за исключением того, что режим маршрутизации требует, чтобы очередь указывала ключ маршрутизации при привязке коммутатора, и сообщение будет перенаправлено в очередь, соответствующую ключу маршрутизации.

Подходящая сцена:

  • Доставка почты
  • Подписка на сцену
  • Отправить смс

5. Тематический режим: Сопоставьте ключ маршрутизации с шаблоном. В это время очередь должна быть привязана к шаблону. "#" соответствует одному или нескольким словам, а "*" соответствует только одному слову.

Процесс:

  • 1. Генератор сообщений генерирует сообщение и отправляет сообщение коммутатору.
  • 2. Коммутатор неопределенно соответствует соответствующей очереди в соответствии с правилами ключа, и наблюдающий потребитель очереди получает потребление сообщений, каждый потребитель слушает свою собственную очередь и устанавливает ключ маршрутизации с подстановочным знаком.

Подходящая сцена:

  • Различные ситуации, о которых сообщает пользователь

5. Практическое использование RabbitMQ

1. Обеспечьте успешную доставку сообщения

Как обеспечить успешную доставку сообщения? Возьмем дело, которым я собираюсь заняться на этот раз, оно связано с вопросами капитала и бухгалтерского учета.Если сообщение не будет доставлено успешно, будут ошибки. Я многое пропустил, как пользовательский опыт эммммммм

Общие решения следующие:

  • механизм подтверждения
  • Механизм автоматической компенсации сообщений
  • Сообщение сохраняется в базе данных для подтверждения фактического статуса сообщения.
  • Задержка доставки сообщений, вторичные проверки, проверки обратных вызовов

механизм подтверждения

Механизм ответа с подтверждением предоставляется rabbitmq и может быть настроен на ручной ответ (автоматический ответ очень ограничен).Когда потребители получают сообщения, они будут отображаться и подтверждаться, когда это необходимо. Потребитель говорит, что я получил сообщение, и RabbitMQ может удалить сообщение из очереди, что можно отобразить, вызвав

channel.basicAck(envelope.getDeliveryTag(), false)

сообщить серверу сообщений удалить сообщение

Механизм автоматической компенсации сообщений

В Rabbit MQ, если бизнес-логика ненормальна, когда потребитель обрабатывает сообщение, механизм компенсации (то есть механизм повторной попытки сообщения) будет выполняться по умолчанию. Если бизнес-логика неверна, сообщение не будет использовано.

механизм хранения сообщений

Механизм хранения сообщений заключается в том, чтобы сохранять запись в базу данных и в то же время постоянно подтверждать статус сообщения, чтобы гарантировать успешное использование сообщения.Вы можете подтвердить статус потребления сообщения в базе данных и в то же время иметь машину для регулярного получения статуса потребления сообщения базы данных.Если статус ненормальный, сообщение будет отправлено повторно.. В то же время вы также можете изменить статус сообщения со слишком большим количеством попыток на сообщение об ошибке, зарегистрировать его и передать программисту для ручной обработки~

###Механизм отложенной доставки сообщений

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

Используется в RabbitMQкоманда задержкиколонка, которая может бытьочередь недоставленных сообщенийреализовать. когда сообщение установленоTTL (время жить)После этого, если его не употребить в течение жизни, он станетмертвая буква. статьмертвая буквасообщения будут доставлены наочередь недоставленных сообщенийПотребителю нужно только отслеживать соответствующую очередь недоставленных сообщений для обработки.

2. Обеспечьте успешное потребление сообщений

Успешная доставка сделана только наполовину, и нам все еще нужно успешно использовать сообщения для удовлетворения наших потребностей.

RabbitMQ автоматически подтверждает (подтверждает), что сообщение правильно обработано по умолчанию, то есть после того, как сообщение доставлено потребителю, он автоматически подтвердит, что сообщение было обработано, и сообщение будет удалено, даже если потребитель выйдет из строя. неожиданно или выдает исключение, если потребитель получает, когда сообщение поступает, оно выходит из строя или выдает исключение до его обработки, тогда сообщение теряется.

Режимы подтверждения сообщения:

  • AcknowledgeMode.NONE: автоматическое подтверждение
  • AcknowledgeMode.AUTO: Подтвердить в зависимости от ситуации
  • AcknowledgeMode.MANUAL: ручное подтверждение

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

3. Сохранение сообщения

Сообщение доставляется в память RabbitMQ, и происходит сбой до того, как оно будет доставлено экземпляру-потребителю.

Сохранение сообщений может быть выполнено для сохранения Exchange, очереди и сообщения на жестком диске.Таким образом, когда RabbitMQ перезапустится, он перезагрузит постоянный Exchange, очередь и сообщение с жесткого диска и повторно доставит сообщение.

В то же время сообщение все еще необходимо сохранить в базе данных.

4. Ограничение тока на стороне потребителя

Если сервер RabbitMQ имеет десятки тысяч необработанных сообщений, и мы открываем клиент-потребитель случайным образом, огромное количество сообщений будет отправлено одновременно, но наш единственный клиент не может обрабатывать столько данных одновременно, и сервер ресурсы исчерпаны и т.д.

RabbitMQ предоставляет функцию qos, то есть при условии неавтоматического подтверждения сообщений, если определенное количество сообщений не подтверждено, новые сообщения не будут потребляться.

5. Последовательные сообщения

Для отправки последовательных сообщений необходимо, чтобы сообщения доставлялись в одну и ту же очередь, а у этого потребителя может быть только одна (монопольный режим), и отправлять ее нужно единообразно (можно объединять в одно большое сообщение, или могут быть разделены на несколько сообщений), и все сообщения имеют одинаковый идентификатор сеанса. Добавьте атрибуты сообщения: порядковый номер метки последовательности и атрибут SIZE текущего сообщения последовательности и выполните операцию сохранения. Принимайте только одно сообщение за раз, выполняйте ACK вручную после обработки, а затем получайте следующее сообщение.

6. Повторное потребление

Повторное потребление является очень опасной проблемой в очередях сообщений, особенно в режиме с несколькими потребителями, если сообщение используется повторно и требует средств, оно часто подвержено финансовым рискам. Поэтому необходимо решить проблему повторного потребления сообщений.

Ключом к тому, чтобы сообщения не использовались повторно, является обеспечение идемпотентности очередей сообщений.

Решение выглядит следующим образом:

1. Уникальный первичный ключ Вы получаете это сообщение, чтобы выполнить операцию вставки базы данных. Это просто, сделайте уникальный первичный ключ для этого сообщения, тогда даже при повторном потреблении это приведет к конфликту первичных ключей. 2. Redis идемпотент Если вы получите это сообщение и выполните операцию установки redis, это легко, и нет необходимости ее решать, потому что результат будет одинаковым независимо от того, сколько раз вы его устанавливаете, а операция установки изначально является идемпотентной операцией. . 3. Потребительские СМИ Подготовьте сторонний носитель для записей потребления. Возьмем, к примеру, redis, присвоим сообщению глобальный идентификатор и напишем в redis в форме K-V, пока сообщение потребляется. Прежде чем потребители начнут потреблять, они могут зайти в Redis, чтобы проверить, есть ли записи о потреблении.

Шестое, построение кластера RibbitMQ

Существует два типа кластеров RabbitMQ.нормальный кластеризеркальный кластер.

1. Общий кластер:

Возьмем два узла (rabbit01, rabbit02) в качестве примера для описания. Два узла rabbit01 и rabbit02 имеют только одни и те же метаданные, то есть структуру очереди, но объект сообщения существует только в одном из узлов, rabbit01 (или Rabbit02).

После того, как сообщение попадает в очередь узла rabbit01, когда потребитель использует узел rabbit02, RabbitMQ временно передает сообщение между rabbit01 и rabbit02, извлекает объект сообщения в A и отправляет его потребителю через B.. Следовательно, потребитель должен попытаться подключиться к каждому узлу и получить от него сообщения. То есть для одной и той же логической очереди должны быть установлены физические очереди на нескольких узлах. В противном случае, независимо от того, подключен ли потребитель к Rabbit01 или Rabbit02, выход всегда будет в Rabbit01, что создаст узкое место.

Когда узел Rabbit01 дает сбой, узел Rabbit02 не может получить неиспользованные объекты сообщений в узле Rabbit01. Если сообщение сохраняется, узел rabbit01 должен быть восстановлен, прежде чем его можно будет использовать. Если нет настойчивости, произойдет явление потери сообщения.

2. Зеркальный кластер:

На базе обычных кластеров нужные очереди делаются в зеркальные очереди.Сущность сообщения будет активно синхронизироваться между зеркальными узлами, а не временно извлекать данные, когда клиент извлекает данные, то есть столько сообщений узла будет резервироваться, сколько копий.. Побочные эффекты этого режима также очевидны: помимо снижения производительности системы, при слишком большом количестве зеркальных очередей и большом количестве входящих сообщений пропускная способность сети внутри кластера будет сильно расходоваться этим синхронным взаимодействием. Поэтому он подходит для случаев с высокими требованиями к надежности.

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

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

7. Каковы недостатки внедрения промежуточного программного обеспечения сообщений в архитектуру системы?

Хоть миддлвар сообщений и хорош, но лучше его не использовать или стараться не использовать, ведь отвязка системы вызовет какие-то другие проблемы.

Снижение доступности системы: С введением MQ в системе появилась еще одна зависимость. Зависимости, если они пойдут не так, могут привести к снижению доступности системы. После внедрения промежуточного программного обеспечения необходимо рассмотреть, как оно развертывается и как обеспечить высокую доступность.

Снижение стабильности системы: внедрение MQ может привести к множеству запутанных проблем из-за сетевых сбоев, сбоев промежуточного программного обеспечения, исключений потребителей и т. д., тем самым снижая стабильность системы.

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

Даже если есть так много проблем, учитывая, что распределенная архитектура в настоящее время является основным направлением, система с высокой степенью связанности с трудом справляется с растущим числом пользователей, а распределенная среда нуждается в промежуточном программном обеспечении сообщений для обеспечения эффективной и надежной доставки сообщений, поэтому мы нужно, чтобы было ясно, когда использовать какие сообщения middleware. Познай себя и врага, и тебе не грозит опасность в сотне битв.

Эпилог

Эта глава кратко знакомит с RabbitMQ. Нет необходимости писать конкретный метод построения или говорить об используемом методе. Это содержание четко реализовано в Интернете. Вы также можете посмотреть его самостоятельно. Следуйте инструкциям, чтобы построить его. Лучше усвойте содержание этой главы.

В то же время, если вам нужна интеллект-карта, вы можете обратиться ко мне, ведь чем большим количеством знаний вы делитесь, тем оно ароматнее!