Публикация №305 от 03.05.2023
Сведения, приведенные в настоящей статьи основаны на использовании брокера сообщений RabbitMQ в качестве транспортной среды для коммуникации в микросервисной архитектуре. Под организацией приема сообщений понимается логическая надстройка основного обработчика входящих сообщений, которая зависит от бизнес-требований. Реализация логической надстройки в настоящей статье не приводится так как ее реализация допускается на разных языках программирования и программных архитектурах. В статье рассматриваются проблемы обработки сообщений между сервисами, возникающие на высоких нагрузках. Под высокими нагрузками понимаются относительные величины различных метрик, а не только прямое внешнее воздействие на систему.
Большинство систем, поддерживающих внутренний обмен сообщениями через брокер сообщений, например, RabbitMQ, имеют отправителя сообщения, один или множество получателей (если задача, которую они выполняют может быть разделена на параллельные вычисления). Брокер сообщений, как правило, не имеет никаких обработок уровня бизнес-требований и содержит исключительно транспортные настройки, которые не учитывают содержание сообщений и сложность алгоритмов для их обработки. С точки зрения модульной разработки систем, такой подход оправдан.
С ростом сложности произвольной системы, увеличивается количество сообщений, их интенсивность, расширяется разнообразие обслуживающих алгоритмов. В системе возникают различные отрицательные эффекты, которые при низкой нагрузке и малой размерности системы незаметны, либо исключены полностью. Основная проблема - избыточность вычислений, которые занимают ресурсы, как следствие, снижают скорость обработки очередей сообщений в целом. Избыточные вычисления успешно скрываются на фоне больших нагрузок и становятся одним из первых факторов сдерживающих вычислительный потенциал системы.
Для решения задачи идентификации избыточных вычислений необходимо выделить основные сущности и их характеристики, которые участвуют в процессе обмена сообщениями.
В силу архитектурных особенностей произвольного проекта, передаваемые сообщения можно разделить на следующие типы:
Первые два типа имеют существенные различия для применения в бизнес-модели данных, накладывают ограничения на характер работы с сообщениями.
К сообщениям с полезными данным относятся такие данные, которые не требуют дополнительной информации для обработки, считаются и записываются или передаются в том виде, в котором были получены принимающей стороной.
Примеры данных:
Преимущества:
Недостатки:
К сообщениям с ссылкой на полезные данные относятся такие данные, которые требуют дополнительного запроса информации к первоисточнику по ссылке.
Преимущества:
Недостатки:
Примеры данных:
Сообщения, образующие сигналы, по свойствам схожи с сообщениями с ссылкой на полезные данные. С той лишь разницей, что в сигналах отсутствуют полезные данные.
Некоторые сигналы могут быть пропущены (удалены). Например, сигнал на обновление кеша данных.
Некоторые сигналы не могут быть пропущено (удалены). Например, сигнал, по сути являющийся счетчиком событий. Такой сигнал нельзя пропускать, даже если сигналов получено аномально много за короткий промежуток времени, иначе счетчик будет посчитан неверно.
Сообщения с полезными данными | Сообщения с ссылкой на полезные данные | Сообщения, образующие сигналы | |
---|---|---|---|
Удаление дубликатов | Нет | Да/Нет | Да/Нет |
Изменяемость данных | Нет | Да | - |
Размер данных | Большой | Малый | - |
Буферизация применяется для увеличения производительности за счет предварительной обработки.
Способы обработки:
Удаление сообщение в общем случае не предусмотрено системами передачи сообщений. Системы доставки сообщений не вправе изменять и тем более удалять сообщения. Любая модификация данных — это область бизнес-требований, которые справедливо отсутствуют в явном виде в брокерах сообщений. Тем не менее, с ростом систем, появляется и увеличивается необходимость в промежуточном слое между системой передачи сообщений и принимающей стороной. Удаление избыточных сообщений — один из важных методов обработки сообщений с целью увеличения производительности.
В основе удаления лежит ключ идемпотентности, по умолчанию, происходящий из хеша полезных данных сообщения.
Удаление дубликатов сообщений без буфера должно происходить за определенный промежуток времени.
Пакетная обработка — важная способность высокопроизводительной системы.
Буферизированные сообщения можно передать в виде итераций с каждым сообщением, либо одним пакетом (массивом). Заметный эффект от пакетной обработки возникает тогда и только тогда, когда алгоритм обработки единого пакета данных происходит одним целым, а не разбирается на отдельные сообщения в цикле.
Так, например, СУБД, в большинстве случаев, быстрее выполнит SQL-запрос, если в нем указать весь перечень данных в условии, а не перебирать условия раздельно. Особенно, это касается процедур СУБД, обрабатывающих данные.
Буфер входящих сообщений достаточно описать следующими характеристиками:
Опустошение буфера необходимо делать, если в буфере хранится максимальное количество сообщений. В данном случае происходит сброс сообщений на обработку в виде одного пакета или итераций по каждому сообщению при наполнении буфера. Данная стратегия опустошения буфера удобна при быстром поступлении обращений.
Опустошение буфера необходимо делать, если заранее неизвестно время наполнения буфера. В данном случае происходит сброс сообщений на обработку в виде одного пакета или итераций по каждому сообщению при достижении общего времени наполнения буфера.
Данная стратегия опустошения буфера удобна при медленном наполнении очереди, когда ожидание достижения максимального размера не может быть спрогнозировано в разумные сроки.
Опустошение буфера по времени ожидания ближайшего сообщения — это частный случае опустошения буфера по общему времени ожидания, который рассчитан на большой размер буфера.
Данная стратегия опустошения подходит в случаях размеренного наполнения буфера, когда между сериями сообщений возникает пауза.
С ростом нагрузки на систему и объема обрабатываемых сообщений возникает необходимость вынужденного замедления обработки. Такая ситуация возникает при большом количестве сообщений и быстрой обработке таких сообщений. Если передаваемые сообщения являются сигналами или сообщениями, передающие ссылки (без сохранения состояний) — фактически, которые не обязательно обрабатывать 1000 раз в секунду, а достаточно обработать 1 раз в секунду или реже. В растущей системе сложно заметить момент когда начинают выполняться избыточные вычисления.
Системы с необходимостью вынужденного замедления выглядят так:
Администратор системы не выявит аномалий потому, что все показатели соответствуют нагрузке и выглядят оптимальными, но на самом деле выполняется огромный объем вычислений, которые можно не выполнять.
Для решения проблемы используется буфер с удалением дубликатов. Величина буфера устанавливается исходя из типовой нагрузки, может составлять сотни или тысячи сообщений. Длительность общего времени ожидания сообщений устанавливается исходя из бизнес-ограничений. Как правило 1 секунды достаточно.
Входящие сообщения обрабатываются различными алгоритмами. Одни алгоритмы быстры и способны обрабатывать сотни тысяч сообщений в секунду, а другие могут обработать 1 сообщение за 3 секунды. Качество алгоритмов в настоящей статье не рассматривается. p>
Важно понимать, что алгоритмы существует разные и не всегда возможно ускорить их вычисления.
Для корректного определения настроек буфера предлагается отнести сообщения и вычисления следующим образом:
Вычисления / Скорость поступления входящих сообщений | Быстрые вычисления | Средние вычисления | Медленные вычисления |
---|---|---|---|
Быстрая скорость поступления | Нормальная очередь, высокая вероятность избыточных вычислений, высокая нагрузка | Вероятность переполнения очереди, нормальная нагрузка | Переполнение очереди, высокая нагрузка |
Средняя скорость поступления | Нормальная очередь, нормальная нагрузка | Нормальная очередь, нормальная нагрузка | Переполнение очереди, высокая нагрузка |
Низкая скорость поступления | Свободная очередь, низкая нагрузка | Свободная очередь, средняя нагрузка | Свободная очередь, высокая нагрузка |
В случае ошибок в работе принимающей стороны, в очередь возвращается сообщение и очередь не уменьшается. Новые сообщения так же продолжают поступать в очередь. При высоких нагрузках количество сообщений в очереди растет лавинообразно. Накопить сообщения в очереди помогают и бизнес-требования. Например, сообщения, ожидающие отправки по расписанию. Во всех случаях образованная очередь из сообщений блокирует отправку сообщений на некоторое время, созданных в настоящий момент (срочных).
Обработка массивных очередей позволяет исключать дубликаты сообщений за период, если это разрешено бизнес-требованиями.
Для решения задачи обработки срочных сообщений используется второй пул очередей. Когда каждое новое сообщение приходит в первый пул очередей, а в случае сбоев, новое сообщение возвращается во второй пул очередей. Таким образом каждое новое сообщение всегда обрабатывается свободным пулом (в пределах текущей нагрузки), а ошибочные сообщения или сообщения в ожидании, обрабатываются вторым пулом, где срочность обработки стоит на втором плане.
Ссылка на статью: https://altermodus.ru/ru/articles/305/