Для того, чтобы было понятно о чём ниже пойдёт речь — небольшая справка:
- Кварта Технологии — поставщик решений в области базовой ИТ-инфраструктуры и лидер российского ИТ-рынка в области полной информационной и технической поддержки технологий для встраиваемых систем на базе Microsoft Windows Embedded.
- ТехноКом работает в области разработки и производства систем ГЛОНАСС/GPS спутникового мониторинга транспорта, персонала, датчиков контроля топлива и программного обеспечения для любых компаний и отраслей транспорта, промышленности и сельского хозяйства. Самый известный продукт компании навигационные терминалы серии «АвтоГРАФ».
- iQFreeze — решение от Кварта Технологии, которое собирает, обрабатывает и передаёт информацию о состоянии груза и транспорта в реальном времени.
Создание базового прототипа шлюза
Система АвтоГРАФ представляет собой классическое клиент-серверное приложение с возможностями доступа к данным и аналитике. Её текущая архитектура обуславливает высокую стоимость масштабирования. Именно поэтому ключевой идеей для совместной работы стала попытка переосмыслить архитектуру, приведя её к модели SaaS для решения проблем с масштабируемостью и создания инновационного предложения для рынка.
Перед началом проекта было очевидно, что проведение технологического взаимодействия в парадигме Интернета Вещей может стать весьма сложной задачей, так как включает в себя, помимо интеграции сервисов Azure в уже существующее ПО, ещё и вопросы, касающиеся получения данных с установленного на транспорте оборудования – терминалов спутникового мониторинга транспорта АвтоГРАФ (далее по тексту «терминалы СМТ»). И только соответствующая подготовка значительно упрощает задачу. Поэтому подготовка началась примерно за месяц до начала самого мероприятия. В результате были обсуждены несколько ключевых вопросов, которые приведены ниже с ответами на них.
Запущена ли система в эксплуатацию? Какое состояние имеют устройства, что они умеют делать и что не умеют?
На сегодня система работает несколько лет. Так как она была предназначена для использования с транспортом различных производителей/партнёров, есть различия в оборудовании. Почти все устройства похожи только в одном — изменение прошивки даже на небольшом их количестве не представляется возможным по причине их работы в продуктивной среде. По этой причине использование модели Field Gateway (размещение либо установка шлюза близко к устройствам) невозможно.
Какой протокол используют устройства для связи с серверной частью?
Бинарный протокол собственной разработки компании ТехноКом.
Возможно ли создать новую версию серверной части, не нарушив происходящие процессы, и перенаправить их туда со старой версии?
Сложно, но реально. Но так как подобный подход требует серьёзного и долгосрочного тестирования и разработки, было решено исключить его из данной итерации.
Нужно ли управлять устройствами удалённо?
Возможно, в будущем, но не сейчас.
В процессе планирования было решено расширить список задач в связи с добавлением к системе компонентов для обработки собираемых данных. Соответственно, текущая монолитная архитектура должна была быть разбита на модули. Был организован поступающий поток данных из АвтоГРАФа, поэтому вопросы, касающиеся эмуляции устройств, были закрыты.
Для хостинга шлюза, слушающего TCP-порт и передающего данные в подсистему обработки данных, был выбран облачный сервис Microsoft Azure Cloud Services.
Для того, чтобы реализовать прототип у команды было 5 часов и 3 разработчика на 6 задач:
- Оценить текущую архитектуру и переосмыслить её, используя PaaS.
- Реализовать тестовый шлюз (консольное приложение) для проверки работы.
- Оценить существующие опции для создания облачного шлюза (например, Azure IoT Gateway, Cloud Services и так далее).
- Провести миграцию шлюза в облако.
- Соединить шлюз с подсистемой обработки данных (то есть, написать код для этого).
- Добавить в прототип возможности мониторинга с помощью Application Insights.
Изначально решили сосредоточиться на вопросе о том, как разбить монолитное приложение на компоненты.
Архитектура до
Старая архитектура представляла собой классическую двухзвенную архитектуру «Клиент — сервер», монолитное приложение, написанное на C++ и работающее в среде Windows Server. Его работа заключалась в том, чтобы принимать пакеты данных от мониторинговой системы, установленной на устройствах, сохранять эти пакеты в локальном хранилище и быть фронтендом для доступа к данным для внешних пользователей. Внутри приложения было несколько модулей: сетевой, хранения данных, расшифровки данных и работы с базой данных.
Данные между сервером и устройствами передавались по проприетарному бинарному TCP-протоколу. Для установки подключения клиент отсылает handshake-пакет, сервер должен был на него ответить пакетом подтверждения.
В своей работе приложение использовало набор системных вызовов Win32API. Данные хранятся в бинарной форме в виде файлов.
Проблема масштабирования подобной заключается в ограниченности способов реализации: увеличение ресурсов сервера/добавления нового и настройка балансировщика нагрузки и выполнения других задач.
Архитектура после
После применения новой архитектуры приложение потеряло свою актуальность, так как по сути, оно было шлюзом и выполняло несколько служебных задач (например, по сохранению данных без их изменения). В новой архитектуре всё это было заменено на сервисы Azure (разработчики оценивали, какую опцию лучше выбрать: Azure IoT Gateway или написанный собственноручно шлюз; и выбрали второй вариант с хостингом в Azure Cloud Services).
Принципы функционирования новой системы аналогичны принципам работы старой, однако предоставляют дополнительные возможности по масштабированию (в том числе автоматическому) и снимают инфраструктурные задачи, например, по настройке балансировщика нагрузки. Несколько экземпляров (инстансов) Cloud Service со шлюзом прослушивают специальный порт, подключают устройства и передают данные в подсистему их обработки.
Перенос прототипа на облачную платформу Microsoft Azure с использованием модели Software as a Service (SaaS)
Важно начинать с небольших шагов и не реализовывать всё сразу в облаке. Облако имеет свои преимущества и особенности, которые могут усложнить прототипирование (например, открытие портов, отладка удалённого проекта, развертывание и так далее). Поэтому в данном случае первый этап разработки заключался в создании локальной версии шлюза:
- Шлюз слушает TCP-порт и при получении handshake-пакета от устройства инициирует подключение.
- Шлюз отвечает ACK-пакетом и устанавливает подключение. При получении пакетов данных, согласно спецификации, эти пакеты раскладываются на готовый контент.
- Шлюз пересылает данные дальше.
В процессе создания прототипа возникла проблема — разработчики работали в офисе Microsoft, где сетевой периметр безопасности имеет определённое количество различного рода политик, что могло привести к усложнению прототипирования локального шлюза. Так как возможности изменять политики не было, команда воспользовалась ngrok, который позволяет создать безопасный туннель на localhost.
Во время разработки было еще несколько вопросов, которые было решено проработать глубже — запись на локальное хранилище, получение адреса и портов инстанса, на котором работает шлюз. Так как в облаке множество переменных меняется динамически, эти вопросы было важно решить до перехода к следующему этапу.
Запись на локальное хранилище Cloud Service
Конечно, по сравнению с локальным хранением данных на инстансе, в Azure есть лучшие способы хранения информации, однако старая архитектура подразумевала локальное хранение, поэтому необходимо было проверить возможна ли работа системы в этом режиме. По умолчанию, все, что работает в Cloud Service, не имеет доступа к файловой системе — то есть просто так взять и записать информацию в c:/temp не получится. Так как это PaaS, необходимо настроить специальное пространство под названием Local Storage в конфигурации облачного сервиса и установить флаг cleanOnRoleRecycle, который с определённой степенью уверенности гарантирует, что информация с локального хранилища не будет удалена при перезапуске роли. Ниже код, который был использован для решения данной задачи.
const string azureLocalResourceNameFromServiceDefinition = "LocalStorage1";
var azureLocalResource = RoleEnvironment.GetLocalResource(azureLocalResourceNameFromServiceDefinition);
var filepath = azureLocalResource.RootPath + "telemetry.txt";
Byte[] bytes = new Byte[514];
String data = null;
while (true)
{
TcpClient client = server.AcceptTcpClient();
data = null;
int i;
NetworkStream stream = client.GetStream();
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
…
System.IO.File.AppendAllText(filepath, BitConverter.ToString(bytes));
…
}
client.Close();
}
После тестирования оказалось, что данные остаются в хранилище, поэтому это может стать неплохим способом для хранения временных данных.
Получение адреса и порта инстанса
Для того, чтобы в runtime получить данные, необходимо определить Endpoint внутри конфигурации облачного сервиса и обратиться к нему в коде.
IPEndPoint instEndpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints\["TCPEndpoint"\].IPEndpoint;
IPAddress localAddr = IPAddress.Parse(instEndpoint.Address.ToString());
TcpListener server = new TcpListener(localAddr, instEndpoint.Port);
Теперь автоматически настраиваемый балансировщик нагрузки будет управлять запросами между инстансами, разработчик же может масштабировать количество этих инстансов, при этом каждый инстанс будет получать необходимые данные в runtime.
Итак, локальный шлюз запущен и протестирован на Cloud Services (который можно эмулировать локально), теперь настала очередь развернуть проект в облако. Инструментарий Visual Studio позволяет делать это в несколько кликов.
Вопрос дальнейшей пересылки данных из инстанса шлюза был успешно закрыт использованием официальных сэмплов кода.
Выводы
При планировании команда беспокоилась о том, что одного дня будет недостаточно для того, чтобы разработать работающий прототип системы, особенно в условиях наличия разнообразных сред, устройств и требований (устаревшие устройства, протоколы, монолитное приложение на С++). Кое-что действительно не успели сделать, но базовый прототип был создан и работал.
Использование для такого рода задач модели PaaS является отличным способом:
- Быстрого прототипирования решения.
- Использования сервисов и настроек для того, чтобы сделать решение масштабируемым и гибким с самого начала.
За несколько часов удалось создать основу для разработки end-to-end решения в парадигме IoT с использованием реальных данных. В планах на будущее — использование машинного обучения для извлечения большей пользы из данных, миграция на новый протокол и тестирование решения на платформе Azure Service Fabric.
Благодарим за участие в создании материала Александра Белоцерковского и команду Кварта Технологии.
Комментарии (0)