
Хотите знать, как работает платформа умного дома, обслуживающая десятки и сотни тысяч (а то миллионы!) устройств? А как проводят нагрузочное тестирование таких платформ, когда нужно проверить их поведение при увеличении количества приборов? Ведь это сложно — железок не напасешься! Если я вас заинтриговал, то добро пожаловать в статью, я как раз рассказываю о том, как это все делается. :)
Меня зовут Иван Банников, я работаю в VK Tech. Я ведущий разработчик команды Tarantool CDC, одного из продуктов экосистемы Tarantool, но в статье я расскажу про давние времена, про проект, на котором я познакомился с Tarantool, зафанател от него и в итоге пришел потом работать в Tarantool. Поговорим о платформе для интернета вещей, о ее устройстве, о том, какие в ней могут быть слабые места и как мы их выявляли с помощью нагрузочного тестирования, а также о MQTT.
Устройство платформы умного дома
Умный дом — это система бытовых устройств, способная выполнять определенные задачи без участия человека. Это могут быть всякие разные датчики, розетки, камеры, освещение, роботы-пылесосы, кухонная техника и многое другое. Важно то, что этими приборами можно управлять дистанционно и все они могут взаимодействовать между собой, а также общаться с неким командным центром.
Дистанционно управлять приборами можно через Bluetooth. Так и было сделано в случае приборов того бренда, для которого мы строили платформу умного дома. Мобильное приложение подключается к приборам, передает им команды, получает от них ответы и состояние. Это уже можно назвать умным домом, но только лишь отчасти. Почему? Потому что возможности сильно ограничены — техника управляется только в пределах действия Bluetooth. Находясь в удалении от приборов, например на даче или в офисе, нельзя посмотреть температуру в комнате или включить чайник, чтобы, придя домой, сразу попить горяченького чайку.
Чтобы решить эту проблему, разработали дополнительное устройство — шлюз. Шлюз подключается к умным приборам по Bluetooth и обменивается с ними сообщениями и в то же время подключается через Wi-Fi-роутер с интернетом к MQTT-брокеру. Через брокер шлюз общается с другими агентами, например с мобильным приложением или с платформой интернета вещей (он же IoT — Internet Of Things). Таким образом, чтобы пользователь мог управлять своей техникой на большом расстоянии, ему достаточно купить и поставить дома такой шлюз и настроить его.
Возможностей становится больше: к системе можно подключать различные интеграции, например голосовые помощники или сервисы повседневной автоматизации вроде IFTT. Получаем полноценную IoT-платформу.
Пара слов об MQTT: это специализированный протокол публикации небольших наборов данных в интернете вещей. Основная сфера его применения — доставка небольших сообщений, например показателей датчиков, или обмен командами между устройствами.
И наконец, добавим еще один компонент к нашей платформе. Для интеграций был разработан специальный сервис на базе Tarantool (вот где он, наконец, появился!), через который другие сервисы, например голосовые помощники, могли управлять устройствами. Также этот сервис по запросу проводит удаленную диагностику устройств, что существенно упростило работу технической поддержки, которая порой очень страдала от недовольных пользователей и не понимала, что им отвечать.

Почему именно Tarantool? Все просто — это не только быстрая in-memory-база данных, но еще и производительный сервер приложений, и такое сочетание позволяет разрабатывать мощные процессинговые системы. Об этом я рассказывал в статьях:
Но Tarantool не главный герой этой статьи, хотя о нем тоже будет сказана пара слов :)
Итак, мы разобрались, что такое платформа умного дома и как она работает. Поехали дальше. Теперь самое интересное!
Авария и реанимация

От мониторинга поступает сигнал тревоги: 100%-я загрузка процессоров машины, на которой крутится MQTT-брокер. И это прод. Все плохо: отказывает удаленное управление приборами, к шлюзам никак не подключиться, мобильное приложение ругается, что нет связи. Дальше — хуже: мы видим совершенно непонятный шторм сообщений, сервис интеграции на Tarantool и MQTT-брокер обмениваются между собой каким-то просто безумным количеством команд. Все это привело к полному отказу системы: сначала удаленное управление полностью отпало, потом сервис интеграций перестает управлять приборами (но не падает!) и отваливаются голосовые помощники. Бизнес-заказчик рвет и мечет, пользователи скандалят, грозятся вернуть устройства в магазины, техподдержка в мыле, мы в полной депрессии. Но делать-то что-то надо!
Тянуть кота за хвост нельзя, а значит, надо реанимировать пациента любой ценой. Превращаемся в реанимационную бригаду, надеваем перчатки, берем дефибрилляторы и начинаем чинить MQTT-брокер.
Первым же действием просто перезапустили брокер и все усугубили: машина загрузилась еще сильнее, да так, что даже SSH к ней работал с перебоями. Стало понятно, что причина где-то глубже и повторная перезагрузка не поможет. При этом в логах ничего внятного, мониторинг только и верещит про 100%-ю загрузку ядер, никаких других метрик вразумительных мы быстро раскопать не смогли. Поэтому самым логичным выходом было не перезагружать брокер, но отключить от него все устройства и заблокировать все подключения к нему.
Кое-как выполняя команды по тормозящему SSH, через iptables заблокировали все подключения по порту MQTT. Отключили все устройства полностью (вопли пользователей стали еще громче, техподдержка уже со стеклянными глазами, нервно хихикает), но дождались, пока брокер остынет. После чего выдохнули, подумали и разрешили подключиться небольшой части устройств — открыли чаcть диапазона IP-адресов. Брокер моментально среагировал, накалившись докрасна, но так же быстро остыл и продолжил работать. Уже хорошо. Открыли еще один кусок диапазона — сработало.
И так постепенно открыли весь диапазон и подключили все устройства. Систему восстановили, пользователи написали, что все заработало, мониторинг выдал штатные показатели. Успокоились и пошли дальше работу работать.

Следующий «приступ» случился через неделю. Потом еще через несколько дней. И еще. И еще! И еще!!! И ЕЩЕ!!! И стали эти аварии настолько частыми, что не могло не сказаться негативно на пользовательском опыте. Да, мы научились реанимировать систему, но качество сервиса все равно плохое: кому же захочется иметь дома умную технику, которая в любой момент может отказать?
Расследование
Начали кропотливо изучать метрики в мониторинге, донастроили логирование и вообще стали изучать нашу систему пристальным взглядом. И вот на что мы обратили внимание. Сетевой мониторинг показывал, что в моменты таких аварий количество подключений к брокеру возрастало кратно — почти в 10 раз. Также было много переподключений и отказов брокера в подключении. То есть выглядело так, будто каким-то мистическим образом становилось больше шлюзов, а потом они куда-то исчезали. В логах много сообщений о том, что шлюзы многократно пытаются авторизоваться на брокере. Но опять же, больше ничего путного. В чем же дело?
Убийца — дворецкий TLS?

Разработчики, делавшие прошивки для устройств и шлюзов, изучили логи, посмотрели в исходники прошивок и сказали нам, что у шлюзов есть проблемы с TLS-сертификатами. Брокер принимал подключения только по зашифрованному соединению. Для этого в прошивки шлюзов было вшито три TLS-сертификата, и срок действия одного из них уже истек. А шлюз был устроен так, что он пробовал сертификаты по очереди.
Это частично объяснило проблемы с переподключениями, но никак не объясняло того, что количество этих переподключений возрастало очень сильно. Как оказалось, проблемы с TLS-сертификатами были ни при чем, но мы очень много времени потратили на них.
Дли-и-и-и-и-и-и-и-нная магистраль

Зацепок никаких нет, попытки воспроизвести ситуацию на тестовом стенде с помощью подручных средств не давали никакого результата. Пришлось выдвигать гипотезы и как-то их проверять. И мы обратили внимание на одну интересную вещь. Большинство приборов находится в России, а IoT-платформа развернута на серверах Digital Ocean в европейских ЦОДах. И между шлюзами и брокером очень длинная интернет-магистраль.
Также мы увидели, что шлюзы выставляют очень жесткие параметры поддержания сессии MQTT, что было не очень хорошо. Дело в том, что подключение к MQTT-брокеру делается по TCP и оно долгоживущее. Если ответ на команду PING протокола MQTT не прилетает вовремя, соединение обрывается и шлюз должен переподключиться.
Предположили, что проблемы на интернет-магистрали, приводящие к задержкам сетевых пакетов, могут спровоцировать обрывы соединений с последующей лавиной переподключений, что выглядело в итоге как натуральная DDoS-атака.
Можете задать резонный вопрос — а как это так? Мы можем ходить на европейские и западные сайт и никаких задержек не видим, все летает! На самом деле, в мире web такие вещи не так заметны, поскольку существуют браузерные кэши, фронтенд выполняет множество запросов в параллели и если парочка из них отвалилась — это может быть и не очень заметная задержка. А для слабых железок, коими и являлись наши шлюзы, все это очень критично.
Для подтверждения гипотезы доработали сервис интеграций на Тарантуле, чтобы он выдавал дополнительные метрики, такие как время прохождения сообщений и команд, и стали наблюдать. В итоге мы увидели довольно существенную корреляцию — перед тем, как начинался приступ, пакеты начинали существенно тормозить, и это стало видно на метриках!
А что Tarantool?

На Tarantool мы тоже пристально посмотрели и захотели разобраться, что за шторм сообщений возникал, почему Tarantool начинал генерировать безумное количество управляющих команд. Предположили, что так сказываются особенности взаимодействия со шлюзами. Дело в том, что, когда шлюзы подключаются к брокеру, они отправляют сообщения о своем состоянии — что они живы и способны принимать команды. Tarantool принимает эти сообщения, инициирует создание управляющих сессий, посылает определенные команды и начинает периодически пинговать шлюзы по MQTT. И в случае задержек Tarantool отправляет команду на закрытие управляющей сессии и потом на создание новой сессии.
В итоге получалась лавина сообщений. Когда брокер сильно загружен, время прохождения сообщений через него увеличивается, а это значит, начинается петля обратной связи — снова обрывы сессий и снова отправки команд. И это тоже очень сильно нагружало брокер. При этом, когда MQTT-брокер раскалялся докрасна, Tarantool же держался молодцом — всего 20% CPU :)
Тем не менее все обозначенные выше причины так и не объяснили до конца всей картины происходящего. Чтобы показать уровень абсурда, приведу немного цифр:
Всего в системе было около 7 тысяч шлюзов.
Через шлюзы управлялось до 14 тысяч Blutetooth-устройств.
Активных пользователей — 4 тысячи.
И всего у 3 тысяч активных пользователей были подключены интеграции с голосовыми помощниками.
При таком количестве устройств до по-настоящему высоких нагрузок далеко, с учетом неплохих серверных мощностей. Очевидно, что узкое место во всей системе — MQTT-брокер, ибо он не способен справляться с тем профилем нагрузки, который у нас периодически возникает. А значит, от лихорадочных и беспорядочных попыток воспроизвести похожую ситуацию пора переходить к серьезному инженерному эксперименту — нагрузочному тестированию.
MQTT под давлением
Любой эксперимент начинается с подбора инструментов и планирования. Проанализировав популярные инструменты для НТ, поняли, что они мало подходят под наши задачи. Вот что мы посмотрели:
Locust — хорошо известный в мире Python инструмент для нагрузочного тестирования API. Использует gevent для работы с легковесными «зелеными» потоками, из-за того он не подошел, потому что с ним очень плохо стыковалась библиотека paho-mqtt. С одного узла locust больше 100 подключений создавать не удавалось.
K6 — отличный инструмент, но с ним был один нюанс: чтобы хорошо работало, надо писать не на JavaScript, который медленный, а на Go. Ни JavaScript, ни Go на тот момент не являлись нашими повседневными языками, а тратить время на их освоение не хотелось.
Gatling — инструмент из мира Java. Хорошо известный, но у него была совершенно непонятная поддержка MQTT. Посмотрели и решили, что слишком долго разбираться, и отложили в сторону.
Jmeter — к тому моменту мы просто уже устали и решили уже не рассматривать его. Тем более это Java, и тоже не очень понятно, как jmeter работает с MQTT, поэтому было принято решение написать свой набор инструментов.
Что же мы взяли в качестве основы:
Python — наш основной язык разработки.
Asyncio — хорош в сетевых задачах, используется в нашем стеке технологий.
Gmqtt — хорошая асинхронная библиотека на Python/asyncio, с поддержкой MQTT5.
Multiprocessing — для поддержки многоядерности.
Определившись с набором инструментов, стали думать, как создавать нагрузку, имитировать множество приборов. Мы умеем подключаться к MQTT-брокеру, посылать сообщения, получать и анализировать их.
Первой идеей было написать эмулятор физического объекта. К примеру, взять чайник и попробовать написать его физико-математическую модель: рассчитать, сколько времени он будет нагревать залитую в него воду до 100 градусов, сколько воды испаряется и какие при этом будут показания температуры. Но вскоре пришли к выводу, что такая эмуляция очень дорогая и не имеет смысла. С точки зрения IoT-платформы важнее сетевое поведение этого умного чайника — какие сообщения он посылает, какие принимает и как он на них реагирует. Моделирование всех физических процессов, протекающих в бытовом приборе, не нужно. Это позволило нам воссоздать нужные сценарии и эмулировать большое количество виртуальных устройств.
С появлением эмуляторов связана интересная история. На дворе стояли пандемийные времена, все сидели дома, и поэтому отладить взаимодействие прибора с платформой было нетривиальным делом — нужно было сначала прибор вместе со шлюзом отвезти на дом к сотруднику, все настроить и, конечно же, как-то физически повзаимодействовать со всем этим, понажимать на кнопки, чтобы проверить, как что работает. Весь цикл отладки мог легко растянуться на неделю, а то и на две. Когда мы написали эмуляторы и стали их применять, цикл отладки всех сервисов интеграций сократился буквально до одного дня! Также эмуляторы позволили легко покрыть систему интеграционными тестами.
Итак, инструментарий написан, отлажен, начинаем наш эксперимент.
Первые неудачи
Первый запуск был неуспешным. Мы подняли единомоментно 7 тысяч виртуальных шлюзов, до 14 тысяч виртуальных приборов, подключенных к шлюзам, и… Ничего. Брокер даже не заметил эту нагрузку. Стенд повторял полностью окружение прода, вплоть до параметров ядра операционной системы. Стали разбираться, и оказалось, что есть проблема в asyncio — в версии Python 3.8 asyncio вызывал синхронную функцию для DNS-Resolve в thread pool’е, из-за чего последний (thread pool) забивался. В результате многие соединения создавались намного позже. Взрывной нагрузки не получилось. Проблему решили просто — заменили DNS-имя брокера на его IP-адрес.

Второй запуск оказался чуть лучше — брокер действительно стал нагружаться, и максимальная нагрузка составила 60% от всех доступных ядер. Но это все равно было совсем не то — до такого же состояния, как на проде во время аварий, он не доходил.
Возможно, проблема в том, что брокер плохо отрабатывает подключения по TCP? Проверили, запустив одновременно удвоенное количество соединений к брокеру (то есть уже 14 тысяч), но не посылая ему никаких сообщений и не подписываясь ни на какие топики. И опять ничего. Мониторинг не показывал ни малейшего увеличения потребления процессора. Таким образом, отбросили гипотезу о том, что проблема, возможно, кроется в обработке подключений по TCP.
Поскольку вся система была такая же, как на проде, все настройки одинаковые, то единственное различие крылось только в том, что к проду подключались настоящие физические шлюзы, а на НТ мы подключали эмуляторы. Значит, эмуляторы не совсем точно воспроизводят поведение приборов. Нужно это несоответствие исправлять.
Что есть MQTT
Для того чтобы было понятно, что же на самом деле произошло и как мы докопались до причины, нужно уделить внимание протоколу MQTT.
MQTT — это протокол, в основе которого лежит идея подписки на публикации (publish-subscribe). Есть набор тем (топики), в которые можно публиковать сообщения и на которые можно подписываться. Клиент, подключившийся к брокеру MQTT, может заявить о том, что он хочет получать сообщения на интересующие его темы, посылать сообщения в какие-то темы ну и, собственно, получать и обрабатывать эти сообщения. Темы организованы иерархически и представлены в виде строки, разделенной косыми чертами (слешами).

Рассмотрим пока на очень простом примере. Есть температурный датчик и лампочка. Мы хотим, чтобы лампочка зажигалась, если от градусника поступят сигналы, что температуры ниже 18 градусов, и гасла, если поступят сигналы, что температуры повысилась до 23 градусов. Температурный датчик подключается к брокеру и посылает в топик /devices/temperature/values сообщения с измеренной температурой. Он только посылает сообщения и ни на что не подписывается. Лампочка подключается к брокеру, подписывается на топик /devices/temperatures/values и получает подтверждение от брокера, что она успешно подписалась на этот топик, после чего она начинает получать сообщения от градусника. Если подключить несколько лампочек и подписать на этот же топик, они все будут получать одинаковый поток сообщений.
Так что же было не так
Итак, с базовыми идеями MQTT разобрались. Посмотрим же, что у нас было не так, в чем разница между реальными шлюзами и нашими эмуляторами.
С эмуляторами приборов (лампочек, чайников и прочего) все было нормально, их задача — только генерировать и обрабатывать сообщения. Не в порядке были эмуляторы шлюзов. Настоящий железный шлюз, когда подключается к брокеру, на каждый топик посылает по отдельному запросу на подписку, то есть отдельный пакет SUBSCRIBE. А я в своем эмуляторе шлюза по простоте душевной подписывался одним пакетом SUBSCRIBE сразу на все нужные топики, такое MQTT тоже позволяет. Сработала привычка стараться оптимизировать все как можно раньше. Исправив это расхождение, повторили эксперимент.

И у нас получилось! Влегкую мы положили MQTT-брокер на лопатки, да так, что пришлось перезагружать машину, на которой он работал. Теперь в наших руках есть способ воспроизводить ситуацию, и мы начали целенаправленно искать причины, настраивать логирование и мониторинг.
А что же Tarantool
А с Tarantool все было хорошо. После того как мы нашли стабильный способ воспроизведения проблемы, мы решили провести еще один эксперимент для подтверждения гипотезы со штормом сообщений. Мы сказали сервису Tarantool: закрой все сессии с приборами, которые у тебя открыты, и начинай все заново. Сказано — сделано. Tarantool сделал большой бабах послушно все выполнил и тем самым создал сильный шторм сообщений, который также загрузил брокер почти до 100%. При этом сам Тарантул тратил от силы 10% от одного ядра. Несмертельно, но! В сочетании с остальными факторами это становилось серьезной проблемой, способной довести нагрузку до критической точки, когда происходил полный отказ.
Ну так что же с MQTT-брокером-то?
А с MQTT-брокером мы стали копать. Изучали метрики, смотрели логи, старались подмечать все подозрительное, что может хоть как-то сигнализировать о причинах проблемы. В процессе этого мы улучшили свой мониторинг и логирование, так, чтобы они захватывали максимум информации в случае аварий, и это важный момент, на что следует обращать внимание при построении любых систем: как себя ведет мониторинг во время аварийных ситуаций. Это существенно упрощает последующий разбор инцидентов. Но я отвлекся. Что же мы нашли? В логах мы нашли запись следующего вида (за точность не ручаюсь за давностью лет):
{subscribe_timeout, <0.128.19>, [{topic, «/a/b/c/...»}, {…}]}
{subscribe_timeout, <0.128.20>, [{...}, {…}]},
{subscribe_timeout, <0.128.204>, [{...}, {...}]}
И таких записей было много. Наводит на мысль, что плохо с подписками. Пообщались с разработчиками брокера, поизучали код, поняли, что в принципе подписки в MQTT — вещь не самая простая и не самая легкая.
Как мы помним, топики организованы в иерархию, подписываться можно не на топик целиком, а по маске, по префиксу. Например, есть множество топиков /A/B/C, /A/D/E и /A/F/C, и можно подписаться не только по полному пути, но и по префиксу (SUBSCRIBE /A/#), по маске (SUBSCRIBE /A/+/C). А это все приводит к тому, что брокер должен строить такую сложную вещь, как дерево подписок. И чем сложнее иерархия топиков, тем развесистее дерево подписок, тем дольше искать подписчиков для каждого сообщения.
Поиск подписчиков начинается с корня, и дальше проходит обход дерева, практически целиком. И основной проблемой для реализации хорошего брокера является проблема обхода дерева подписок — чем он быстрее обходит его и находит подписчиков, тем он лучше работает.

Раскапывая брокер EMQX, который мы использовали, мы также рассматривали вариант замены бесплатной версии на платную, в которой, как обещалось, все необходимые оптимизации сделаны. Но увы, стоила она как космический корабль, поэтому было решено разобраться своими силами, докопаться до проблемы и как-то или исправить ее, или найти замену.
Немного об архитектуре EMQX
Общими словами обрисую архитектуру брокера EMQX. В ней выделяется ряд сетевых модулей, которые работают с сетью, протоколом MQTT, очередями и каналами, и выделяется модуль, который и занимается подписками, их хранением и обработкой. В нем и заключалась проблема.
Брокер написан на Erlang — а эта платформа не самая быстрая, хоть она и продвинута во многих смыслах. И для хранения и обработки подписок использовалась встроенная распределенная СУБД Mnesia, которая также на Erlang. И по моему опыту на тот момент, Mnesia до сих пор оставалась довольно плохо проработанной СУБД, которая не справлялась с большими нагрузками. Так что о попытке как-то самостоятельно исправить проблему не могло быть и речи — переворошить надо практически весь код брокера, настолько в нем все было сильно завязано на Mnesia. По всей видимости, платная версия того же брокера сильно отличается — в качестве хранилища предлагают использовать другие СУБД, например Redis.
Поиски нового брокера
Надо искать новый брокер. И тут уже важно сформулировать требования поиска:
Оптимизированное хранение и обработка подписок — умение справляться с большим количеством пакетов SUBSCRIBE, не теряя в качестве обслуживания.
Поддержка расширений.
Кластеризация (способность к горизонтальному масштабированию).
Если по обработке подписок требование понятно, то про поддержку расширений и кластеризацю следует упомянуть подробнее. Дело в том, что EMQX примечателен тем, что поддерживает большое количество различных расширений, дополнений, интеграций, с различными аналитическими системами, хранилищами и часть IoT-платформы была построена с учетом этих возможностей.
Поэтому архитекторам на заметку: любые нестандартные расширения и плюшки — это всегда риск. Каким бы ни было хорошим выбранное решение, рано или поздно придется столкнуться с выбором: менять его или пытаться решать его проблемы.
Требование про кластеризацию обосновывалось тем, что потенциально готовились увеличивать тираж умных приборов. И вот мы нашли такой брокер — что иронично, тоже написанный на Erlang, но работал он гораздо лучше. Называется VerneMQ.
Как же так? Я только что говорил, что Erlang — это плохо! На самом деле, Erlang вполне хорош в сетевых задачах (а для них он и разрабатывался), а вот тяжелая вычислительная часть была выполнена на LevelDB. А это встраиваемая база данных для хранения данных типа «ключ — значение», написанная на C++, очень хорошо оптимизированная, быстрая. Изучив различные нюансы вроде лицензий, кода, сравнив его с EMQX, быстро поставили на стенд и провели тесты. И вуаля! Все нагрузочные тесты, которые ранее ломали EMQX, он легко прошел, даже не чихая толком!
А как же наш любимый Mosquitо
Не подошел, однако. Хотя он единственный из всех брокеров мог влегкую проходить нагрузочные тесты, потребляя всего 15% от одного ядра. Очень производительный брокер, с радостью бы его поставили, но… Требования, требования, увы…
К чему пришли в итоге

Мы стали искать предел производительности VerneMQ и достигли такового при количестве эмуляторов шлюзов около 350 тысяч, а приборов и вовсе в районе миллиона. Для нас это был огромнейший запас, можно смело забыть о проблемах машстабирования лет этак на пять вперед. Мы переписали все необходимые интеграции, провели дополнительно тестирование с отказами и восстановлением (DR), и вскоре VerneMQ заработал на проде.
Но это еще не все! В ходе всех изысканий, экспериментов мы получили важные знания о системе и их постарались учесть.
Доработали сервис с Tarantool. В ходе тестирования с большим количеством приборов выяснилось, что Тарантул должен общаться с брокером по нескольким соединениям, по каждому из которых передается отдельный поток сообщений со своим приоритетом. Так, сообщения, передающие команды, обрабатываются с высоким приоритетом, а сообщения, передающие отчеты о состоянии устройств, которые постоянно обновляются, сообщения с результатами сканирования эфира bluetooth, обрабатываются с более низким приоритетом, их можно даже терять, пропускать в случае надобности.
Научили сервис с Tarantool растягивать во времени нагрузку. То есть откладывать открытие управляющих сессий на шлюзах, если наблюдается высокая нагрузка. Тем самым смягчили штормы сообщений.
Вынесли работу с TLS/SSL на Nginx. VerneMQ не работает с шифрованными соединениями, это делает за него Nginx. Это решение в духе unix way — одна программа должна делать только дело, но делать его хорошо. Это позволило повысить производительность системы еще на 10%.
Перенесли всю платформу в российское облако. В итоге пользователи стали замечать, что приборы стали быстрее реагировать на команды, а также гораздо меньше отваливаться и переподключаться. По-хорошему такую операцию надо было провести с самого начала, так как чем ближе к пользователю сервера, тем лучше, и это снизило бы частоту самопроизвольного появления проблем с нагрузкой на брокер. Но новый брокер мы тоже поставили не зря — никто не отменял обслуживание системы, где может вполне возникнуть необходимость перезагрузить машины, и тогда старый брокер также бы горел и не справлялся со взрывной нагрузкой.
Вот такая вышла детективная история со счастливым концом — убийца-дворецкий найден и обезврежен, и на его место нанят хороший дворецкий, который никого не собирается убивать. =)
Вступайте в чат сообщества Tarantool и подписывайтесь на наш канал в Telegram.