Зачем использовать промежуточное ПО для сообщений MQ?Эти 3 пункта заставят вас полностью понять!

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

предисловие

Человек, который использует очереди сообщений, не знаю почему, это немного смущает. Без рассмотрения этого пункта легко задаться вопросом и начать ерунду.
Ответ: На этот вопрос мы отвечаем только на три основных сценария применения.Неоспоримо, что есть и другие, но только три основных, а именно следующие шесть слов:
Развязка, асинхронность, отсечение пиков

1. Развязка

Традиционный режим:

Недостатки традиционного режима:

Связь между системами слишком сильна. Как показано на рисунке выше, система A напрямую вызывает код системы B и системы C в коде. Если система D будет подключена в будущем, системе A необходимо изменить код, который слишком хлопотно!

Шаблон промежуточного программного обеспечения:

Преимущества шаблона промежуточного программного обеспечения:

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

2. Асинхронный

Традиционный режим:

Недостатки традиционного режима:

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

Шаблон промежуточного программного обеспечения:

Преимущества шаблона промежуточного программного обеспечения:

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

3. Отсечение пиков

традиционный режим

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

Шаблон промежуточного программного обеспечения:

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

Каковы недостатки использования очередей сообщений?

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

Снижение доступности системы:

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

Сложность системы увеличивается:

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

Как выбрать очередь сообщений?

Позвольте мне сначала сказать, что блоггеры знают только ActiveMQ, RabbitMQ, RocketMQ, Kafka и не понимают других MQ, таких как ZeroMQ, поэтому они могут давать ответы только на основе этих четырех MQ.
Анализ: Поскольку в проекте используется MQ, вы должны заранее изучить популярные MQ в отрасли.Если вы даже не знаете преимущества и недостатки каждого MQ, вы можете использовать определенный MQ в соответствии со своими предпочтениями или копать по проекту котлован.
Если интервьюер спросит: «Зачем вы используете этот MQ?».
Вы отвечаете прямо: «Лидер решает».
Этот ответ очень низкий.
Опять же, не копайте яму для компании.
Мы видим, что версии RabbitMQ выходят гораздо чаще, чем ActiveMq. Что касается RocketMQ и kafka, то я вам показывать не буду, короче они более активны, чем ActiveMQ. Подробности можете проверить сами.
Еще одна таблица сравнения производительности
На основании вышеизложенных материалов выделяются следующие два пункта:

1. Для малых и средних софтверных компаний рекомендуется выбирать RabbitMQ.

С одной стороны, язык erlang по своей сути характеризуется высоким параллелизмом, а его интерфейс управления очень удобен в использовании.
Как говорится, успех — это тоже Сяо Хэ, и поражение — это тоже Сяо Хэ! Его недостатки тоже здесь.Хотя RabbitMQ с открытым исходным кодом, сколько программистов в Китае могут настроить erlang?
К счастью, сообщество RabbitMQ очень активно и может устранять ошибки, возникающие в процессе разработки, что очень важно для малых и средних компаний.
Причина, по которой не рассматривают RocketMQ и kafka, заключается в том, что, с одной стороны, малые и средние софтверные компании не так хороши, как интернет-компании, и объем данных не так велик, при выборе промежуточного программного обеспечения сообщений следует отдавать предпочтение тем с более полными функциями, поэтому кафка исключена.
Причина, по которой не рассматривают RocketMQ, заключается в том, что RocketMQ производится Али.Если Али откажется от обслуживания RocketMQ, малые и средние компании, как правило, не смогут нанимать людей для индивидуальной разработки RocketMQ, поэтому это не рекомендуется.

2. Крупные компании-разработчики программного обеспечения выбирают между RocketMq и Kafka в зависимости от конкретного использования.

С одной стороны, у крупных софтверных компаний достаточно средств для построения распределенной среды и достаточно большого объема данных.
Что касается RocketMQ, крупные компании-разработчики программного обеспечения также могут привлекать людей для настройки разработки RocketMQ, ведь в Китае довольно много людей, которые могут изменить исходный код JAVA.
Что касается kafka, в зависимости от бизнес-сценария, если есть функция сбора логов, kafka определенно является первым выбором. Какой из них выбрать, зависит от сценария использования.

Как обеспечить высокую доступность очереди сообщений?

Как было сказано во втором пункте, после введения очередей сообщений снижается доступность системы.
В продакшене никто не использует очереди сообщений в автономном режиме.
Поэтому, как квалифицированный программист, вы должны иметь глубокое представление о высокой доступности очередей сообщений.
Если интервьюер спросит: «Как ваше промежуточное ПО для сообщений обеспечивает высокую доступность?»
Если ваш ответ просто показывает, что вы можете только подписаться и публиковать новости, интервьюер задастся вопросом, не играете ли вы сами с этим и никогда не использовали его в продакшене.
Поэтому, пожалуйста, будьте программистом, который любит думать, умеет думать и понимает мышление.
Ответ. Для ответа на этот вопрос требуется глубокое понимание кластерного режима очередей сообщений.
Взяв rcoketMQ в качестве примера, его кластер имеет режим с несколькими ведущими, режим асинхронной репликации с несколькими ведущими и несколькими подчиненными, режим синхронной двойной записи с несколькими ведущими и несколькими подчиненными.
Схема архитектуры развертывания в режиме multi-master-multislave (нашла в сети, лень, лень рисовать):
На самом деле, когда блогер впервые увидел эту картинку, он почувствовал, что это похоже на kafka, но кластер NameServer был заменен на zookeeper в kafka, который используется для сохранения и обнаружения master и slave.
Процесс общения выглядит следующим образом:
Производитель устанавливает постоянное соединение с одним из узлов (случайно выбранным) в кластере NameServer, периодически получает информацию о маршрутизации Topic от NameServer, устанавливает постоянное соединение с мастером-брокером, который предоставляет услуги Topic, и регулярно отправляет пульс на сервер. Маклер.
Производитель может отправлять сообщения только Мастеру-брокеру, но Потребитель отличается от него, он устанавливает длительное соединение с Мастером и Слейвом, которые одновременно предоставляют услуги Темы, Он может подписываться на сообщения от Мастера-брокера и от Слейва-брокера. .
Так что насчет кафки, для сравнения и иллюстрации схемы топологии кафки (тоже нашел, лень рисовать)

Как показано на рисунке выше, типичный кластер Kafka содержит несколько производителей (которые могут быть просмотрами страниц, созданными веб-интерфейсом, или журналами сервера, системным процессором, памятью и т. д.) и несколько брокеров (Kafka поддерживает горизонтальное расширение, как правило, чем больше брокеров, тем больше (выше пропускная способность кластера), несколько групп потребителей и кластер Zookeeper.
Kafka управляет конфигурацией кластера через Zookeeper, выбирает лидеров и выполняет перебалансировку при изменении группы потребителей.
Производители используют режим push для публикации сообщений брокерам, а потребители используют режим pull для подписки и получения сообщений от брокеров.
Что касается RabbitMQ, то здесь также есть общий режим кластера и зеркального кластера, в нем относительно просто разобраться самостоятельно, и разобраться можно за два часа.
Требуется, чтобы, отвечая на вопросы о высокой доступности, вы могли логично и понятно нарисовать собственную архитектуру MQ-кластера или четко описать ее.

Как сделать так, чтобы сообщения не использовались повторно?

На самом деле, другой способ задать этот вопрос — как обеспечить идемпотентность очередей сообщений?
Эту проблему можно считать фундаментальной проблемой в области очередей сообщений. Другими словами, это проверка ваших дизайнерских способностей.Ответ на этот вопрос можно дать в соответствии с конкретными бизнес-сценариями, и однозначного ответа нет.
Ответ: Позвольте мне сначала поговорить о том, почему это вызывает повторное потребление?
На самом деле, независимо от того, какая очередь сообщений, причины повторного потребления на самом деле схожи.
В обычных условиях, когда потребитель потребляет сообщение, он отправляет подтверждающее сообщение в очередь сообщений после завершения потребления.Очередь сообщений будет знать, что сообщение было использовано, и удалит сообщение из очереди сообщений. Просто информация о подтверждении, отправляемая разными очередями сообщений, имеет разные формы.
Например, RabbitMQ отправляет подтверждающее сообщение ACK, RocketMQ возвращает флаг успеха CONSUME_SUCCESS, а kafka фактически имеет концепцию смещения.
Проще говоря (если вы не понимаете, идите и найдите запись kafka в мастер-руководстве), то есть каждое сообщение имеет смещение.После того, как Kafka использует сообщение, ему нужно отправить смещение, чтобы очередь сообщений знайте, что он поглотил его.
В чем причина повторного потребления?
Именно из-за сетевой передачи и других сбоев информация подтверждения не передается в очередь сообщений, поэтому очередь сообщений не знает, что она использовала сообщение, и снова распределяет сообщение среди других потребителей.
Как решить эту проблему? Ответьте на следующие вопросы для бизнес-сценариев

1. Например, вы получаете это сообщение, чтобы выполнить операцию вставки в базу данных.

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

Как обеспечить надежную передачу потребления?

Анализ: в процессе использования очередей сообщений мы должны следить за тем, чтобы сообщения не потреблялись больше или меньше. Если не удастся обеспечить надежную передачу, это может принести компании десятки миллионов имущественных убытков.
Точно так же, если во время использования не учитывается надежная передача, не роет ли это яму для компании?
Опять же, серьезно относитесь к каждому проекту и не копайте ямы для компании.
Ответ: На самом деле, для этой надежной передачи каждый MQ должен быть проанализирован с трех точек зрения: производитель теряет данные, очередь сообщений теряет данные и потребитель теряет данные.

RabbitMQ

1. Производитель теряет данные

С точки зрения производителей, теряющих данные, RabbitMQ предоставляет режимы транзакций и подтверждения, чтобы гарантировать, что производители не потеряют сообщения.
Механизм транзакций заключается в том, что перед отправкой сообщения откройте транзакцию (channel.txSelect()), а затем отправьте сообщение, если что-то пойдет не так в процессе отправки, транзакция будет откатана (channel.txRollback()), и если передача прошла успешно, транзакция будет отправлена ​​(channel.txCommit()).
Недостатком, однако, является то, что пропускная способность падает. Поэтому, по опыту блогеров, в продакшене чаще всего используется режим подтверждения.
Как только канал перейдет в режим подтверждения, всем сообщениям, опубликованным на канале, будет присвоен уникальный идентификатор (начиная с 1).
Как только сообщение будет доставлено во все соответствующие очереди, rabbitMQ отправит подтверждение производителю (содержащее уникальный идентификатор сообщения).
Это позволяет производителю узнать, что сообщение прибыло в очередь назначения правильно.Если RabiitMQ не сможет обработать сообщение, он отправит вам сообщение Nack, и вы сможете повторить операцию.
Код для обработки Ack и Nack выглядит следующим образом (код сказать не могу, украду):

2. Очередь сообщений теряет данные

Чтобы справиться с потерей данных в очереди сообщений, обычно включается конфигурация постоянного диска.
Эта конфигурация сохраняемости может использоваться в сочетании с механизмом подтверждения.Вы можете отправить сигнал Ack производителю после того, как сообщение будет сохранено на диске.
Таким образом, если rabbitMQ будет уничтожен до того, как сообщение будет сохранено на диске, производитель не получит сигнал Ack и автоматически отправит его повторно.
Так как настойчиво, кстати, на самом деле очень просто, достаточно следующих двух шагов
1. Установите для постоянного идентификатора прочной очереди значение true, что означает, что это постоянная очередь.
2. При отправке сообщения установите deliveryMode=2
После этой настройки, даже если rabbitMQ зависнет, данные можно будет восстановить после перезапуска

3. Потребители теряют данные

Потребители теряют данные, как правило, из-за режима автоматического сообщения подтверждения.
В этом режиме потребители автоматически подтверждают получение информации. В это время rahbitMQ немедленно удалит сообщение.В этом случае, если потребитель не сможет обработать сообщение из-за исключения, сообщение будет потеряно.
Что касается решения, достаточно ручного подтверждающего сообщения.

kafka

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

1. Производитель теряет данные

В производстве Кафки в основном есть один лидер и несколько последователей. Последователь будет синхронизировать информацию лидера.
Поэтому, чтобы предотвратить потерю данных производителем, выполните две следующие настройки.
Первая конфигурация — установить acks=all на стороне производителя. Такая конфигурация гарантирует успешную отправку сообщения после завершения синхронизации подчиненного устройства.
Установите retries=MAX на стороне производителя, после сбоя записи это будет повторяться бесконечно.

2. Очередь сообщений теряет данные

Для случая потери данных в очереди сообщений это не что иное, как зависание лидера до синхронизации данных, в это время зоокпеер переключит других фолловеров на лидера, и данные будут потеряны.
В этом случае необходимо выполнить две настройки.
параметр replication.factor, это значение должно быть больше 1, то есть каждый раздел должен иметь как минимум 2 копии
Параметр min.insync.replicas, это значение должно быть больше 1, это требует от лидера, по крайней мере, осознавать, что есть хотя бы один фолловер, и поддерживать связь с самим собой.
Сочетание этих двух конфигураций и конфигурации вышеупомянутого производителя может в основном гарантировать, что kafka не потеряет данные.

3. Потребители теряют данные

В этом случае смещение автоматически фиксируется, и тогда вы зависаете в процессе обработки программы. Кафка думает, что вы с этим справились.
Опять же, для чего смещение?
смещение: относится к индексу, потребляемому каждой группой потребителей в теме кафки.
Проще говоря, сообщение соответствует нижнему индексу смещения.Если смещение отправляется каждый раз при потреблении данных, следующее потребление начнется с отправленного смещения плюс один.
Например, в теме 100 фрагментов данных, и я израсходовал 50 фрагментов данных и отправил их, тогда смещение, отправленное записью сервера kafka в это время, равно 49 (смещение начинается с 0), тогда смещение будет потребляется с 50 при следующем потреблении.
Решение также очень простое, просто измените его на ручную отправку.

Как обеспечить порядок сообщений?

Анализ: не у всех компаний есть такая бизнес-потребность, но стоит рассмотреть этот вопрос.
Ответ: В ответ на эту проблему, по определенному алгоритму, сообщения, которые нужно держать в порядке, помещаются в одну и ту же очередь сообщений (раздел в kafka, очередь в rabbitMq). Затем используйте только одного потребителя для обработки очереди.
Некоторые люди спросят: что, если есть несколько потребителей, потребляющих пропускную способность?
На этот вопрос нет фиксированного ответа. Например, у нас есть операция Weibo, отправка Weibo, написание комментариев и удаление Weibo, эти три асинхронные операции. Если это такой бизнес-сценарий, просто попробуйте еще раз.
Например, если вы, потребитель, впервые выполнили операцию по написанию комментария, но в это время Weibo еще не был размещен, значит, написать комментарий не удалось, и вам нужно какое-то время подождать. Ожидание, пока другой потребитель сначала выполнит операцию написания комментария, а затем выполнит ее, может быть успешным.
Короче говоря, в ответ на эту проблему моя точка зрения состоит в том, чтобы гарантировать, что очередь находится в упорядоченном порядке, а порядок после выхода из очереди остается за потребителем, чтобы гарантировать отсутствие фиксированной рутины.

Суммировать

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

Наконец

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