При разработке архитектуры программного обеспечения Datapath.io мы быстро внедрили распределенные микросервисы. Цель состоит в том, чтобы измерить небольшой набор ключевых показателей эффективности Интернета (KPI). Это произошло после того, как мы решили, какой язык программирования использовать. Для получения желаемых результатов измерений мы используем Java.

Потребности в распределенных микросервисах

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

Вторая потребность - в нем должен быть механизм для поддержания стабильного соединения между одноранговыми узлами. Это очень важно, поскольку Интернет меняет свою базовую топологию и инфраструктуру. Межсетевые экраны могут измениться, сеансы Border Gateway Protocol (BGP) могут дать сбой, а подсети могут быть недоступны.

AMQP RabbitMQ может противостоять этим сценариям сбоя.

Пример использования Datapath.io AMQP RabbitMQ

В настоящее время мы пингуем Интернет, представленный хостом в сетевом префиксе. Мы пингуем каждые 30 минут из более чем 80 точек по всему миру. Также помним, что результат передается в центральное хранилище.

Наконец, мы рассмотрели реализации AMQP с популярными клиентами Java. Это привело нас к RabbitMQ. Это реализация на Erlang с упором на простоту и высокую пропускную способность. Кроме того, он содержит функцию сегментирования для горизонтальной масштабируемости. Google использовал RabbitMQ в сценарии с пропускной способностью около 10 миллионов сообщений в секунду. Это выходит за рамки нашего текущего использования, но впечатляет.

Как мы используем RabbitMQ

В качестве модератора мы используем серверный процесс RabbitMQ 3.5.6. Это рассылает наши запросы ping каждые 30 минут и получает результаты. RabbitMQ отправляет сообщения в разные очереди, адресующие разные хосты по всему миру. В результате любой хост в очереди знает, над чем он должен работать.

Затем он компилируется с помощью библиотек Erlang HiPE в Ubuntu 14.04 LTS. Он работает на 16-ядерном хосте с памятью 64 ГБ с конфигурацией по умолчанию.

Когда Ping Receiver / Requester запускается, он подключается к хосту RabbitMQ через аутентификацию. Затем он будет ждать сообщения, чтобы начать работу.

Результаты процесса проверки связи отправляются в другую очередь, называемую приемником проверки связи. Приемник ping получает все сообщения, преобразует их в наш формат данных и сохраняет в кластере HDFS. Так Datapath.io использует большие данные.

Что делать, если происходит сбой в процессе приема ping-запросов?

RabbitMQ также может иметь постоянную очередь. Сообщения хранятся в очереди, пока кто-нибудь их не спросит. К сообщениям можно добавить Time-To-Live. Это сделает их съемными через некоторое время. Представьте себе измерительную станцию, которая теряет связь из-за сбоя сети. Сообщения наводняют сервер RabbitMQ.

Самой большой задачей было улучшить масштабируемость формата сообщений, который мы использовали для общения. Это проблема «Потребителя и производителя».

Масштабируемость RabbitMQ

Если производитель, такой как Ping-Requester, создает больше сообщений, чем потребитель, у вас серьезная проблема. В результате RabbitMQ начинает «дросселировать» очередь. Помните, что проделанная работа в потребителе уже оптимизирована. Решение такое:

Масштабируйте хост потребителя (по горизонтали или вертикали). Для Datapath.io ни то, ни другое не было вариантом. Побочные эффекты горизонтального масштабирования (создание большего количества потребителей) были слишком сложными. Стоимость вертикального масштабирования была слишком высокой.

Решение масштабируемости

В результате было использовано другое решение. Мы начали буферизовать сообщения на стороне отправителя и создали пакеты сообщений по десять тысяч. Это позволило избежать накладных расходов, связанных с AMQP RabbitMQ, и снизить регулирование до нуля.

Теперь мы отправляем 70 сообщений каждые 30 минут тем, кто запрашивает ping. Это проверяет все 635K сетевых префиксов вместо 635K отдельных сообщений. Разница составляет 70 вместо ожидаемых 63; за счет алгоритма очистки буфера.

Помните об использовании формата сериализации. Это меньше накладных расходов, таких как "формат данных". Результаты для Java или сериализации строк могут оказаться слишком хорошими для вашего сценария.

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

Статья изначально опубликована в Блоге Datapath.io.