HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <ul><li><a>Начало проектирования</a></li>
1 <ul><li><a>Начало проектирования</a></li>
2 <li><a>Первый этап. Цифровой портрет IoT-устройства</a></li>
2 <li><a>Первый этап. Цифровой портрет IoT-устройства</a></li>
3 <li><a>Второй Этап. Проектирование сервера сбора данных</a></li>
3 <li><a>Второй Этап. Проектирование сервера сбора данных</a></li>
4 <li><a>Третий Этап. Накопление и передача данных для вторичной обработки</a></li>
4 <li><a>Третий Этап. Накопление и передача данных для вторичной обработки</a></li>
5 <li><a>Четвертый этап. Web-интерфейс и внешнее API</a></li>
5 <li><a>Четвертый этап. Web-интерфейс и внешнее API</a></li>
6 <li><a>5 этап. Мониторинг</a></li>
6 <li><a>5 этап. Мониторинг</a></li>
7 <li><a>Итог:</a></li>
7 <li><a>Итог:</a></li>
8 </ul><p><em>Предлагаем вашему вниманию проектную работу<strong>Артема Данильченко</strong>, выпускника курса "<a>Highload Architect</a>".</em></p>
8 </ul><p><em>Предлагаем вашему вниманию проектную работу<strong>Артема Данильченко</strong>, выпускника курса "<a>Highload Architect</a>".</em></p>
9 <p>Цель моей проектной работы - создать базовую архитектуру платформы для сбора, обработки и хранения данных от IoT-устройств. Данная платформа должна отвечать следующим требованиям:</p>
9 <p>Цель моей проектной работы - создать базовую архитектуру платформы для сбора, обработки и хранения данных от IoT-устройств. Данная платформа должна отвечать следующим требованиям:</p>
10 <ul><li>поддержка различных протоколов транспортного уровня;</li>
10 <ul><li>поддержка различных протоколов транспортного уровня;</li>
11 <li>поддержка различного набора информационных протоколов сбора данных от устройств;</li>
11 <li>поддержка различного набора информационных протоколов сбора данных от устройств;</li>
12 <li>управление потоками данных внутри системы;</li>
12 <li>управление потоками данных внутри системы;</li>
13 <li>интеграции с внешними системами и API;</li>
13 <li>интеграции с внешними системами и API;</li>
14 <li>возможность создания Web-интерфейса для отображения данных.</li>
14 <li>возможность создания Web-интерфейса для отображения данных.</li>
15 </ul><h2><strong>Начало проектирования</strong></h2>
15 </ul><h2><strong>Начало проектирования</strong></h2>
16 <p>Для снижения связности системы проектирование будет вестись с использованием подхода построения микросервисной архитектуры. Отличительными чертами данной архитектуры являются масштабируемость, адаптируемость и эволюционность.</p>
16 <p>Для снижения связности системы проектирование будет вестись с использованием подхода построения микросервисной архитектуры. Отличительными чертами данной архитектуры являются масштабируемость, адаптируемость и эволюционность.</p>
17 <p>Будем считать, что наше "сферическое IoT-устройство в вакууме" будет установлено на беспилотном комбайне или тракторе (например фирмы "Ростсельмаш") и передает следующий набор параметров:</p>
17 <p>Будем считать, что наше "сферическое IoT-устройство в вакууме" будет установлено на беспилотном комбайне или тракторе (например фирмы "Ростсельмаш") и передает следующий набор параметров:</p>
18 <p>- свой уникальный идентификатор. Для простоты считаем, что идентификатор уникален и задается в прошивке устройства или при его первой инициализации/регистрации в сети;</p>
18 <p>- свой уникальный идентификатор. Для простоты считаем, что идентификатор уникален и задается в прошивке устройства или при его первой инициализации/регистрации в сети;</p>
19 <p>- геокоординаты и пространственные данные - широта и долгота, скорость и направление движения;</p>
19 <p>- геокоординаты и пространственные данные - широта и долгота, скорость и направление движения;</p>
20 <p>- системное время;</p>
20 <p>- системное время;</p>
21 <p>- техническое состояние устройства - заряд аккумулятор, уровень сигнала сети, уровень топлива, уровень масла, загруженность бункера, процент износа рабочих узлов и т. д.;</p>
21 <p>- техническое состояние устройства - заряд аккумулятор, уровень сигнала сети, уровень топлива, уровень масла, загруженность бункера, процент износа рабочих узлов и т. д.;</p>
22 <p>- счетчик переданных пакетов данных.</p>
22 <p>- счетчик переданных пакетов данных.</p>
23 <p>Особо стоит обратить внимание на то, что IoT-устройству придется работать в условиях плохого или нестабильного канала передачи данных. А это значит, что необходимо максимально сжимать пакет полезных данных для передачи и использовать различные информационные<a>протоколы</a>.</p>
23 <p>Особо стоит обратить внимание на то, что IoT-устройству придется работать в условиях плохого или нестабильного канала передачи данных. А это значит, что необходимо максимально сжимать пакет полезных данных для передачи и использовать различные информационные<a>протоколы</a>.</p>
24 <h2><strong>Второй Этап. Проектирование сервера сбора данных</strong></h2>
24 <h2><strong>Второй Этап. Проектирование сервера сбора данных</strong></h2>
25 <p>Сервер сбора данных должен предоставлять следующие возможности:</p>
25 <p>Сервер сбора данных должен предоставлять следующие возможности:</p>
26 <ol><li>Поддержка TCP и UDP-протоколов транспортного уровня.</li>
26 <ol><li>Поддержка TCP и UDP-протоколов транспортного уровня.</li>
27 <li>Поддержка протоколов MQTT и LoRaWAN.</li>
27 <li>Поддержка протоколов MQTT и LoRaWAN.</li>
28 <li>Способность выдерживать несколько тысяч одновременных сетевых подключений.</li>
28 <li>Способность выдерживать несколько тысяч одновременных сетевых подключений.</li>
29 <li>Быть экономичным в части потребления ресурсов.</li>
29 <li>Быть экономичным в части потребления ресурсов.</li>
30 <li>Скорость разработки и простота поддержки.</li>
30 <li>Скорость разработки и простота поддержки.</li>
31 </ol><p>Для разработки такого сервера лучше всего подходят языки типа С, С++, Golang, Rust. Поскольку я несколько последних лет пишу исключительно на Golang, то для реализации MVP курсового проекта был выбран Golang.</p>
31 </ol><p>Для разработки такого сервера лучше всего подходят языки типа С, С++, Golang, Rust. Поскольку я несколько последних лет пишу исключительно на Golang, то для реализации MVP курсового проекта был выбран Golang.</p>
32 <p>Следующая проблема, которая возникает при реализации системы, - это источники данных. Не всегда есть под рукой нужные устройства или же их недостаточное количество. Выходом из такой ситуации является разработка своих программных имитаторов.</p>
32 <p>Следующая проблема, которая возникает при реализации системы, - это источники данных. Не всегда есть под рукой нужные устройства или же их недостаточное количество. Выходом из такой ситуации является разработка своих программных имитаторов.</p>
33 <p>Программные имитаторы позволяют решить следующие проблемы:</p>
33 <p>Программные имитаторы позволяют решить следующие проблемы:</p>
34 <ul><li>сэкономить бюджет проекта, не тратиться на закупку большого числа устройств;</li>
34 <ul><li>сэкономить бюджет проекта, не тратиться на закупку большого числа устройств;</li>
35 <li>создавать различные варианты нагрузки (плавное увеличение, DDOS, пиковая нагрузка);</li>
35 <li>создавать различные варианты нагрузки (плавное увеличение, DDOS, пиковая нагрузка);</li>
36 <li>упрощает поддержку и тестирование различных протоколов информационного обмена;</li>
36 <li>упрощает поддержку и тестирование различных протоколов информационного обмена;</li>
37 <li>позволяет моделировать отказы и нештатные ситуации.</li>
37 <li>позволяет моделировать отказы и нештатные ситуации.</li>
38 </ul><p>В курсовом проекте я сделал простую реализацию tcp сервера и имитатора клиента, которые производили обмен открытой ASCII-строкой со списком параметров.</p>
38 </ul><p>В курсовом проекте я сделал простую реализацию tcp сервера и имитатора клиента, которые производили обмен открытой ASCII-строкой со списком параметров.</p>
39 <p>###ID=1234235345&amp;CNT=1&amp;STM=220828003254&amp;LAT=47.257178&amp;LON=39.7633771***</p>
39 <p>###ID=1234235345&amp;CNT=1&amp;STM=220828003254&amp;LAT=47.257178&amp;LON=39.7633771***</p>
40 <p>Для имитации плохого канала связи между имитатором устройства и сервером был развернут прокси "ToxyProxy" (<a>https://github.com/Shopify/toxiproxy</a>).</p>
40 <p>Для имитации плохого канала связи между имитатором устройства и сервером был развернут прокси "ToxyProxy" (<a>https://github.com/Shopify/toxiproxy</a>).</p>
41 <p>Применение этого инструмента позволяет смоделировать задержки в канале передачи данных, timeout сервера, ограничение пропускной способности и т. д.</p>
41 <p>Применение этого инструмента позволяет смоделировать задержки в канале передачи данных, timeout сервера, ограничение пропускной способности и т. д.</p>
42 <p>Итак, в качестве первого сегмента нашей системы мы можем нарисовать вот такую архитектурную схему:</p>
42 <p>Итак, в качестве первого сегмента нашей системы мы можем нарисовать вот такую архитектурную схему:</p>
43 <a></a><h2><strong>Третий Этап. Накопление и передача данных для вторичной обработки</strong></h2>
43 <a></a><h2><strong>Третий Этап. Накопление и передача данных для вторичной обработки</strong></h2>
44 <p>После приема данных сервером их необходимо передать на дальнейшую обработку. Но тут возникает ряд ограничений:</p>
44 <p>После приема данных сервером их необходимо передать на дальнейшую обработку. Но тут возникает ряд ограничений:</p>
45 <ul><li>потребителями данных может быть не одна система;</li>
45 <ul><li>потребителями данных может быть не одна система;</li>
46 <li>данные поступают неравномерно и в пиковые моменты возможна задержка в обработке;</li>
46 <li>данные поступают неравномерно и в пиковые моменты возможна задержка в обработке;</li>
47 <li>должна быть возможность маршрутизация трафика внутри системы.</li>
47 <li>должна быть возможность маршрутизация трафика внутри системы.</li>
48 </ul><p>На помощь приходит один из брокеров сообщений : ZeroMQ, RabbitMQ, NATS.</p>
48 </ul><p>На помощь приходит один из брокеров сообщений : ZeroMQ, RabbitMQ, NATS.</p>
49 <p>Для своего проекта я выбрал NATS (<a>https://docs.nats.io/</a><a>)</a>. Мой выбор обоснован следующими доводами:</p>
49 <p>Для своего проекта я выбрал NATS (<a>https://docs.nats.io/</a><a>)</a>. Мой выбор обоснован следующими доводами:</p>
50 <ul><li>написан на Golang. Не требует дополнительных библиотек и фреймворков. Легко разворачивается на любой системе, даже без Docker;</li>
50 <ul><li>написан на Golang. Не требует дополнительных библиотек и фреймворков. Легко разворачивается на любой системе, даже без Docker;</li>
51 <li>поддержка механизмов Publish-Subscribe, Request-Reply, Streaming, Key/Value Store, MQTT;</li>
51 <li>поддержка механизмов Publish-Subscribe, Request-Reply, Streaming, Key/Value Store, MQTT;</li>
52 <li>простая маршрутизация сообщений;</li>
52 <li>простая маршрутизация сообщений;</li>
53 <li>у меня есть экспертиза по построению систем на базе NATS.</li>
53 <li>у меня есть экспертиза по построению систем на базе NATS.</li>
54 </ul><p>Как было сказано выше, брокер сообщений выступает связующим звеном для различных подсистем платформы:</p>
54 </ul><p>Как было сказано выше, брокер сообщений выступает связующим звеном для различных подсистем платформы:</p>
55 <ol><li>Подсистема обработки входяших сообщений IoT-устройств. В задачи данной системы входит распаковка входящих данных, сохранение их в БД и передача в другие системы для вторичной обработки. Реализация выполнена на Golang + PostgreSQL.</li>
55 <ol><li>Подсистема обработки входяших сообщений IoT-устройств. В задачи данной системы входит распаковка входящих данных, сохранение их в БД и передача в другие системы для вторичной обработки. Реализация выполнена на Golang + PostgreSQL.</li>
56 <li>Подсистема управления устройствами. Отвечает за управление настройками устройств, формирование и передачу новых настроек функционирования устройства (например - частота выхода на связь).</li>
56 <li>Подсистема управления устройствами. Отвечает за управление настройками устройств, формирование и передачу новых настроек функционирования устройства (например - частота выхода на связь).</li>
57 <li>Подсистема уведомлений. Отвечает за централизованную рассылку оповещений по изменению состояния или параметров устройств или объекта наблюдения.</li>
57 <li>Подсистема уведомлений. Отвечает за централизованную рассылку оповещений по изменению состояния или параметров устройств или объекта наблюдения.</li>
58 <li>Подсистема геопозиционирования и картографии. Подсистема для взаимодействия с внешними системами картографии, геопозиционирования, топопривязки. OpenStreetMap, YandexMap, ArcGIS. Так как геоданные являются редкоизменяемыми с долгой актуальностью, для снижения нагрузки на внешние системы и увеличения скорости запросов можно поставить Reddis или аналоги для кэширования данных от внешних систем.</li>
58 <li>Подсистема геопозиционирования и картографии. Подсистема для взаимодействия с внешними системами картографии, геопозиционирования, топопривязки. OpenStreetMap, YandexMap, ArcGIS. Так как геоданные являются редкоизменяемыми с долгой актуальностью, для снижения нагрузки на внешние системы и увеличения скорости запросов можно поставить Reddis или аналоги для кэширования данных от внешних систем.</li>
59 </ol><p>И теперь архитектура платформы принимает вот такой вид:</p>
59 </ol><p>И теперь архитектура платформы принимает вот такой вид:</p>
60 <a></a><h2><strong>Четвертый этап. Web-интерфейс и внешнее API</strong></h2>
60 <a></a><h2><strong>Четвертый этап. Web-интерфейс и внешнее API</strong></h2>
61 <p>Для реализации доступа к данным платформы предлагается сделать 2 API.</p>
61 <p>Для реализации доступа к данным платформы предлагается сделать 2 API.</p>
62 <a></a><p>1.<strong>Public API</strong>. Программный интерфейс доступа для сторонних систем и сторонних разработчиков. Может быть реализован как обычный REST API с авторизацией доступа через jwt-token. Для защиты платформы от от ddos необходимо использовать rate limiter.</p>
62 <a></a><p>1.<strong>Public API</strong>. Программный интерфейс доступа для сторонних систем и сторонних разработчиков. Может быть реализован как обычный REST API с авторизацией доступа через jwt-token. Для защиты платформы от от ddos необходимо использовать rate limiter.</p>
63 <p>2.<strong>Internal API</strong>. Внутренний API используется для обеспечения работы web-компонентов IoT-платформы. Например - мобильный клиент или личный кабинет с доступом через web-браузер. Оптимальным решением для организации работы будет использование gRPC с<a>сериализацией</a>данных через protobuf.</p>
63 <p>2.<strong>Internal API</strong>. Внутренний API используется для обеспечения работы web-компонентов IoT-платформы. Например - мобильный клиент или личный кабинет с доступом через web-браузер. Оптимальным решением для организации работы будет использование gRPC с<a>сериализацией</a>данных через protobuf.</p>
64 <p>Данный подход позволит снизить объем трафика, обеспечить обратную совместимость и расширяемость API.</p>
64 <p>Данный подход позволит снизить объем трафика, обеспечить обратную совместимость и расширяемость API.</p>
65 <p>Любые<a>запросы к серверу</a>должны в обязательном порядке проходить через балансировщик нагрузки. По возможности, данные, которые запрашиваются из БД, должны кэшироваться.</p>
65 <p>Любые<a>запросы к серверу</a>должны в обязательном порядке проходить через балансировщик нагрузки. По возможности, данные, которые запрашиваются из БД, должны кэшироваться.</p>
66 <p>В качестве простой реализации GUI я сделал вывод координат IoT-устройств на карту. Для этого потребовалось написать простой web-сервер на go.</p>
66 <p>В качестве простой реализации GUI я сделал вывод координат IoT-устройств на карту. Для этого потребовалось написать простой web-сервер на go.</p>
67 <a></a><h2><strong>5 этап. Мониторинг</strong></h2>
67 <a></a><h2><strong>5 этап. Мониторинг</strong></h2>
68 <p>Для мониторинга системы можно применять elk+ prometuse.</p>
68 <p>Для мониторинга системы можно применять elk+ prometuse.</p>
69 <p>Для трассировки запросов - opentelemetry.</p>
69 <p>Для трассировки запросов - opentelemetry.</p>
70 <p>В рамках MVP реализация не выполнялась.</p>
70 <p>В рамках MVP реализация не выполнялась.</p>
71 <h2><strong>Итог:</strong></h2>
71 <h2><strong>Итог:</strong></h2>
72 <p>Конечный вариант архитектуры проекта:</p>
72 <p>Конечный вариант архитектуры проекта:</p>
73 <a></a><a></a>
73 <a></a><a></a>