Теоретические обоснования использования микросервисной архитектуры для роботизированных систем
Содержание
- Введение
- Общий концепт архитектуры
- Распространенные архитектурные проблемы и их решение (архитектура приложения)
- Монолитная архитектура против микросервисной архитектуры
- Описание концепта сингулярности любого сервиса
- Vision (зрение)
- Voice (общение)
- Data process (обработка данных)
- Auth (авторизация)
- Устройство базового микросервиса
- Logger (ведение протокола)
- Database (база данных)
- API (интерфейс взаимодействия)
- Реализация сервиса Face recognition (распознавание лиц)
- Business layer (основной функционал)
- I/O (ввод-вывод)
- Масштабирование
- Заключение
- Список литературы
Введение
Цель данной работы - показать, по какому принципу строятся и развиваются современные сервисы. Почему разные на первый взгляд приложения построены крайне похожим и предсказуемым образом.
В первом разделе будут рассмотрены вопросы касаемо часто возникающих проблем при построении архитектуры приложения. Что из себя представляет архитектура сервиса. В чем разница между монолитом и микросервисами и существует ли предел развития технологий.
Второй раздел содержит описание устройства базового микросервиса, способного автономно выполнять свои функции. Будут рассмотрены способы сбора технической информации, хранения данных и авторизации.
В третьем разделе описана реализация сервиса Face recognition.
Общий концепт архитектуры 1 2 3
Любой программный продукт, начиная с момента появления идеи и до потери актуальности уже готового проекта, проходит определенные этапы жизненного цикла. Некоторые из них не являются обязательными, так как зависят в большее степени от бизнес составляющей, но остальные так или иначе присутствуют в независимости от специфики продукта. И безответственный подход к пониманию этих этапов, а точнее процессов, закрепленных за ними, снижает шансы на успешную реализацию конечного продукта.
Обычно жизненный цикл подразумевает следующие этапы:
- Подготовка
- Проектирование
- Дизайн
- Кодирование
- Тестирование
- Документирование
- Внедрение
- Сопровождение
Это достаточно типичный набор для проектов, разрабатываемых по классической каскадной модели, которую также называют waterfall (водопад). Но для других моделей разработки этот набор может быть частично другим, либо иметь иной порядок этапов.
В рамках данной работы рассмотрим обязательный этап жизненного цикла - проектирование.
Архитектурой программного обеспечения называют совокупность важнейших решений об организации программной системы.
Архитектурный шаблон — это обобщенное часто используемое решение распространенной задачи в архитектуре программного обеспечения в заданном контексте.
Еще до непосредственного процесса разработки, технические специалисты проекта, опираясь на полученное техничечкое задание, продумывают архитектуру программной реализации, пытаются предсказать проблемные места и свести задачу к уже известной, для того, чтобы использовать уже готовые архитектурные шаблоны. Это необходимо в первую очередь для того, чтобы не наступил момент, когда дальнейшее развитие проекта станет слишком дорогим или вовсе невозможным, некоторые решения могут быть взаимоисключающими. Правильно построенная архитектура позволяет своевременно предугадать поведение системы при различных сценариях эксплуатации и расширении.
В последнее время все больше внимания уделяется пусть не самой новой, но очень переспективной микросервисной архитектуре.
Микросервисная архитектура — вариант сервис-ориентированной архитектуры программного обеспечения, направленный на взаимодействие насколько это возможно небольших, слабо связанных и легко изменяемых модулей — микросервисов, получивший распространение в середине 2010-х годов в связи с развитием практик гибкой разработки и DevOps.
Если в традиционных вариантах сервис-ориентированной архитектуры модули могут быть сами по себе достаточно сложными программными системами, а взаимодействие между ними зачастую полагается на стандартизованные тяжеловесные протоколы (такие, как SOAP, XML-RPC), в микросервисной архитектуре системы выстраиваются из компонентов, выполняющих относительно элементарные функции, и взаимодействующие с использованием экономичных сетевых коммуникационных протоколов (в стиле REST с использованием, например, JSON). За счёт повышения обособленности модулей архитектура нацелена на уменьшение степени зацепления и увеличение связности, что позволяет проще добавлять и изменять новые и уже готовые реализации в любое время.
Подобный подход позволяет реализовать с наименьшими затратами как вертикальное, так и горизонтальное масштабирование 4. Что позволяет распределить систему между несколькими реальными серверами и повысить отказоустойчивость каждого отдельного микросервиса. А также дублирование микросервисов с использованием специальных балансировщиков позволит перераспределять нагрузки между узлами системы, что позволит плавно наращивать производительность в зависимости от роста числа пользователей и производить обновление программного кода без отключения всей системы.
В качестве критики стоит упомянуть, что по сути разные микросервисы не могут без опосредования обмениваться информацией, так как слабая связность подразумевает обмен через сетевые протоколы. А это означает, что часто разные сервисы адаптированы под использование разных интерфейсов. Отсутствуют универсальные соглашения по этому поводу. Также обмен по сетевым протоколам подразумевает потери производительности, что в теории не так явно при построении монолитной архитектуры.
Под монолитной архитектурой обычно подразумевают наличие общей и единой платформы, где сконцентрированы все компоненты одной программы. В более узком смысле под монолитом понимают приложение, имеющее единственный процесс развертывания, а масштабирование производится при помощи реплицирования исходного проекта.
Среди достоинств монолитной архитектуры можно выделить следующие пункты: 5 6
-
Простая разработка и простой запуск программы. Из-за того, что вся разработка сконцентрирована в одном месте, легче интегрировать инструменты для облегченной разработки. Нет необходимости вносить изменения по отдельности в разных местах, так как вся кодовая база находится в одном месте.
-
Сквозные проблемы практически отсутствуют. Большое количество приложений имеют зависимость от задач, которые совершаются между компонентами программы. При монолитной архитектуре эти проблемы практически отсутствуют, так как все сконцентрировано в одном коде и все работает в одном приложении.
-
Улучшенная производительность. Если учитывать, что приложения были собраны правильно, то одно и то же приложение при монолитной архитектуре будет работать более производительно, чем при микросервисах. Данный пункт является ключевым при разработке малопроизводительных устройств, когда явно существуют ограничения по памяти и скорости.
Все еще достаточно остро обсуждается противостояние микросервисной и монолитной архитектур. Каждый подход имеет свои преимущества и недостатки, которые можно покрыть, но не всегда это является целесообразным.
Упомянем часто приводимые аргументы:
-
С точки зрения дальнейшего развития проекта и увеличения функционала, а так же переиспользуемости все же лидируют микросервисы, так как относительная сложность каждого из компонентов не возрастает. Это достигается принципом единственной ответственности, пришедшим из SOLID принципов.
-
Каждый отдельный микросервис легче и меньше, что облегчает поддержку и обслуживание. Также для микросервисов сокращается время на развертывание и выполнение тестов, что также ускоряет процесс разработки.
-
С другой стороны монолитное приложение не имеет проблем с взаимодействием внутренних компонентов, легко применять оптимизации для их взаимодействий. По этой же причине гораздо проще реализовать E2E тестирование, что при микросервисной архитектуре накладывает определенные трудности.
-
Малой команде разработчиков гораздо проще разрабатывать монолитное приложение. При дефиците технических специалистов таким образом можно ускорить процесс разработки. Также малый продукт не имеет смысла разбивать на микросервисы.
Пусть актуальность монолитной архитектуры постепенно падает, но, очевидно, существуют области применения каждой из этих двух архитектур, и даже со временем некоторые задачи иначе решить не получится.
Сингулярность любого сервиса 7
В данном пункте под сингулярностью подразумевается теоретическая обособленность каждого микросервиса в отдельности.
Микросервис в теории выполняет только одну ключевую функцию, совокупность которых порождает новые возможности и более сложные способы взаимодействия и обработки данных.
Расмотрим на примере простого сервиса.
Пусть необходимо реализовать систему, которая определяет по фото известного ей человека и приветствует его. Декомпозируем задачу на более простые и понизим уровень абстракции для лучшего понимания. Для простоты абстрагируемся от выбора перефирии и предположим, что все необходимое уже установлено и правильно функционирует. Рассмотрим только программную составляющую и архитектуру приложения.
Из условия ясно, что у нас есть точка входа, которая получает изображение, и точка выхода, которая в свою очередь воспроизводит некоторый аудиофайл. Также понятно, что полученные данные как-то обрабатываются и происходит связывание изображения с аудио.
На данном этапе мы получаем набор необходимых микросервисов для построения архитектуры. Во-первых, изображение поступает в сервис, который сравнивает его с известным уже человеком. Очевидно, что для этого потребуется база данных, чтобы была возможность добавлять новых людей в систему.
В теории сервис, который подразумевает хранение данных, необходимо обезопасить от несанкционированного доступа. Для этого требуется создать сервис для аутентификации, но в данном случае это условие лишь упоминается, так как пример теоретический.
Во-вторых, после валидации изображения данные поступают в сервис, который связывает полученную сигнатуру с аудиофайлом. Предположим, что аудиофайлы не хранятся в базе для каждого конкретного пользователя, а генерируются на основе строки, которую составляет сервис обработки данных.
В конце сгенерированный файл поступает на устройство вывода и воспроизводится. Это наиболее простой сценарий.
Далее рассмотрим каждый сервис в отдельности.
Vision (зрение)
Задача по распознаванию образов целиком реализуется алгоритмами машинного обучения. Наш сервис по распознаванию состоит из обертки над таким алгоритмом. Данный программный компонет получает изображение с камеры и запускает цепочку вызовов остальных сервисов.
То есть микросервис можно раздробить на его оболочку, которую мы используем непосредственно в наших условиях, и алгоритм обработки изображения. Каждый из этих компонентов заменим, но делить их уже не имеет смысла, так как отдельно от каждого из них нет пользы. Полагаем, что данная программа максимально декомпозирована с точки зрения функционирования и составляет полноценный микросервис.
Data process (обработка данных)
Данный сервис также как и его предшественник состоит из оболочки, через которую реализуется получение данных и дальнейшая ее отправка, и алгоритма обработки поступивших данных.
В данном случае потребуется обращение к базе данных для получения данных о человеке, чье изображение поступило на вход системе. После успешного получения данных алгоритм составляет строку приветствия на основе ответа и передает ее дальше.
База данных
Это сервис для хранения данных.
Оболочкой этого сервиса точно так же получает запрос, извлекает данные (либо делает иные действия над данными) и возвращает их.
Voice (общение)
Задача по генерации аудиофайлов также решается при помощи машинного обучения. Архитектура микросервиса как и в прошлых примерах состоит из обертки и алгоритма.
Обертка в свою очередь получает строку, которую передает для создания аудио, а потом отправляет на устройство вывода.
Архитектура такого сервиса показана на изображении ниже.

Как видно из описания микросервисов, каждый из них имеет практически одинаковую структуру, которую возможно модифицировать при необходимости. Каждый такой микросервис выступает в роли детали конструктора, что позволяет абстрагироваться от реализации сложной системы связывания алгоритмов. Любой микросервис выполняет только одну задачу, это дает возможность переиспользовать его в других проектах. Вся работа сводится к построению правильной архитектуры.
Теперь попробуем изменить архитектуру приложения и покажем, как просто можно изменить способ взаимодействия компонентов программы.
В прошлом примере микросервисы были связаны по цепочке на подобие конвейера. Такой способ применим, но имеет недостаток. Если необходимо добавить еще один шаг обработки данных, то придется добавлять изменения в компонент, стоящий перед встраиваемым, и адаптировать логику этого компонента для вызова конкретного следующего шага конвейера.
Организуем структуру таким образом, что общением со всеми микросервисами будет заниматься один из них. Например, сервис по обработке данных.

Новая архитектура приложения подразумевает иной способ взаимодействия.
Устройство ввода отправляет изображение в сервис обработки данных. Этот сервис по очереди передает данные в нужные микросервисы и конечный результат выдает на устройство воспроизведения аудио. Для реализации этой архитектуры необходимо изменить поведение оболочек микросервисов. Теперь при завершении работы каждый микросервис передает данные обратно сервису, который к ним обратился. То есть теперь при добавлении новых программных компонентов нет необходимости затрагивать уже существующие.
Любой микросервис можно свести к минимальной реализации, в этом и заключается принцип сингулярности микросервисов.
Устройство базового микросервиса 8
Рассматривая микросервисную архитектуру, взглянем на устройство каждого отдельного микросервиса.

Абстрактно каждое приложение имеет ряд компонентов, без которых решение определенной задачи практически невозможно. Каждый микросервис состоит из таких частей:
- Интерфейс взаимодействия. API - Application Programming Interface (Интерфейс Программирования Приложений).
- Модуль авторизации Auth.
- База данных.
- Система логирования.
- Слой бизнес логики. (Основной функционал приложения).
Рассмотрим каждый из них в отдельности.
API
API - это совокупность инструментов и функций в виде интерфейса для создания новых приложений, благодаря которому одна программа будет взаимодействовать с другой.
Существуют разные типы API.
Наиболее распространены во всемирной паутине так называемые Web API, которые используются в качестве платформы для создания HTTP-служб. Среди них выделяют:
RPC (Remote Procedure Call ) – удаленный вызов процедур, SOAP (Simple Object Access Protocol) – простой протокол доступа к объектам, REST (Representational State Transfer ) – передача состояния представления. API можно разделить по типу сервиса, у которого они есть: приложения, вебсайты и операционные системы. Например, у большей части операционных систем (Unix, Windows, MacOS, и т. д.) есть API, благодаря которому возможно программирование сервисов для этих систем.
Также API можно подразделять по типу доступа:
- Внутренние API (доступны внутренним разработчикам компании и сотрудникам, используются для оптимизации рабочих процессов и снижения затрат),
- Партнерские API (доступны бизнес-партнерам и потребителям продукта или услуги, используются для оптимизации процессов и разработки),
- Публичные API (доступны всем, используются для создания новых сервисов и популяризации существующего направления).
В зависимости от назначения сервиса и его архитектуры, приложение так или иначе будет иметь определенный способ взаимодействия с ним. API - это слой соприкосновения с внешними сервисами и пользователями.
Auth
Аутентификация — процедура проверки подлинности, например:
- проверка подлинности пользователя путём сравнения введённого им пароля (для указанного логина) с паролем, сохранённым в базе данных пользовательских логинов;
- подтверждение подлинности электронного письма путём проверки цифровой подписи письма по открытому ключу отправителя;
- проверка контрольной суммы файла на соответствие сумме, заявленной автором этого файла.
Учитывая степень доверия и политику безопасности систем, проводимая проверка подлинности может быть односторонней или взаимной. Обычно она проводится с помощью криптографических способов.
Аутентификацию не следует путать с авторизацией (процедурой предоставления субъекту определённых прав) и идентификацией (процедурой распознавания субъекта по его идентификатору).
Данный модуль необходим для сохранности данных и стабильности системы. По идее каждый сервис также может включать в себя модуль авторизации, но в микросервисной архитектуре для этого изначально подразумевается отдельный сервис, который отвечает только за управление пользовательскими аккаунтами и проверяет подлинность ключей, на основе чего разрешает конкретным пользователям доступ к другим микросервисам приложения.
Базы данных
База данных — совокупность данных, организованных в соответствии с концептуальной структурой, описывающей характеристики этих данных и взаимоотношения между ними, которая поддерживает одну или более областей применения.
Деятельность большинства сервисов подразумевает обработку и хранение данных. Для этих целей были разработаны базы данных.
Базы данных подразделяются по типам. Давайте назовем некоторые из них:
- Реляционые базы данных
- Распределенные базы данных
- Хранилища данных
- NoSQL базы данных
- Графовые базы данных
- Базы данных с открытым исходным кодом
- Облачные базы данных
- Многомодельные базы данных
- Документоориентированные базы данных
- Автономные базы даннных
Каждый из перечисленных типов разработан для решения определенных задач, либо на смену уже устаревшим идеям и реализациям.
Практически каждый микросервис будет использовать те или иные решения в области хранения данных. Но не обязательно каждая такая база данных будет являться частью отдельно взятого сервиса. В некоторых ситуациях имеет смысл вынести логику хранения данных в отдельный сервис и дать возможность работать с ним другим компонентам распределенного приложения.
Логирование
Логированием называют запись логов. На этапе развертывания и работы каждый сервис может вести протокол. Это позволяет отследить причину неполадок в конкретном модуле. Обычно запись логов ведется в специальный файл, который потом использует системный администратор для определения причин разных явлений.
Типы логов
Существуют разные уровни и разные подробности логирования. Когда ошибку сложно воспроизвести, используют максимально подробные логи; если это не требуется, собирают только ключевую информацию. Для работы с логами и поиском информации в огромных текстовых данных используют специализированные инструменты.
Для удобной работы с логами их делят на типы. Это помогает быстрее находить нужные и выбирать правильные инструменты для работы с ними. Например, выделяют:
- системные логи, то есть те, которые связаны с системными событиями;
- серверные логи, регистрирующие обращения к серверу и возникшие при этом ошибки;
- логи баз данных, фиксирующие запросы к базам данных;
- почтовые логи, относящиеся к входящим/исходящим письмам и отслеживающие ошибки, из-за которых письма не были доставлены;
- логи авторизации;
- логи аутентификации;
- логи приложений, установленных на этих операционных системах.
Также логи можно типизировать по степени их важности:
- Fatal/critical error — то, что нужно срочно исправить.
- Not critical error — ошибки, которые не влияют на пользователя.
- Warning — предупреждения, то, на что нужно обратить внимание.
- Initial information — информация о вызовах API сервиса, запросах в БД, вызовах других сервисов.
Бизнес логика
Все, о чем говорилось ранее, в большей степени нужно для реализации взаимодействия с микросервисами на разных уровнях. Можно сказать это внешняя часть. Внутри каждого компонента существует программный код, который и определяет его суть.
Например, сервис авторизации получает запросы на регистрацию и аутентификацию и занимается их обработкой. Это и есть назначение этого сервиса. Внешний сервис логирования получает протоколы от всех подключенных к нему микросервисов. На основе этих данных он мониторит работоспособность всей системы и позволяет оперативно реагировать на любые нештатные ситуации.
Бизнес-логика — это реализация предметной области в информационной системе.
Эта часть приложения как раз и служит причиной выделения ее в отдельный микросервис.
Реализация сервиса Face recognition (распознавание лиц) 9 10
Распознавание лиц — практическое приложение теории распознавания образов, в задачу которого входит автоматическая локализация лица на фотографии и, в случае необходимости, идентификация персоны по лицу. Функцию идентификации людей на фотографиях уже активно используют в программном обеспечении для управления фотоальбомами.
Задача идентификации и распознавания лиц — это одна из первых практических задач, которая стимулировала становление и развитие теории распознавания и идентификации объектов.
Интерес к процедурам, лежащим в основе процесса узнавания и распознавания лиц, всегда был значительным, особенно в связи с возрастающими практическими потребностями: охранные системы, верификация, криминалистическая экспертиза, телеконференции и т.д.
Проблема распознавания лиц рассматривалась ещё на ранних стадиях компьютерного зрения.
Гавный недостаток системы распознавания лиц - это ухудшение качества распознавания при плохой освещенности и изменении положения головы или ракурса.
Существует несколько подходов к построению алгоритмов распознавания лиц: 11
-
Эмпирический метод. Этот подход базируется на правилах, которые использует человек для определения лиц. При данном подходе обычно выделяют то, что лоб ярче, чем центральная часть лица. Также важно наличие на изображении частей лица (носа, рта, глаз). Для определения производится значительное уменьшение участка изображения, где предполагается наличие частей лица, или строятся перпендикулярные гистограммы. Такой алгоритм легко реализовать, но он плохо подходит для изображений, где присутствует большое количество посторонних объектов.
-
Использование инвариантных признаков, характерных для изображения лица. Основой служит снова импирический подход. Метод выявляет характерные части лица, его границу, изменение формы, контрастности и т.д., объединяет все эти признаки и верифицирует. Данный метод может использоваться даже при повороте головы, но при наличии других лиц или неоднородном фоне распознавание становится невозможным.
-
Детектирование лиц при помощи шаблонов, заданных разработчиком. Лицо выступает шаблоном или стандартом. Цель алгоритма - проверить каждый сегмент изображения на соответствие этому алгоритму. Проверку можно производить для разных ракурсов. Проблема алгоритма в том, что он требует множество трудоемких вычислений, что сказывается на скорости его работы.
Все современные алгоритмы распознавания лиц используют системы, обучающиеся с помощью тестовых изображений. Для обучения используют базы с изображениями, содержащими лица, и не содержащими их. Каждый фрагмент изображения характеризуется как вектор признаков, с помощью которого классификаторы определяют, является ли данная часть изображения лицом или нет.
Разные системы используют разные подходы для распознавания, но все они принципиально не различаются.
Для распознавания лица алгоритму необходимо пройти 4 этапа.
-
Обнаружение лица. Для начала камера пытается обнаружить лицо человека. Лучшим сценарием является тот, когда человек смотрит прямо в камеру, но до определенных пределов это не обязательно.
-
Анализ лица. После обнаружения лица начинается анализ фотографии. Обычно рассматривается около 80 узловых точек (расстояние между глазами, форма скул и тому подобные).
-
Конвертация изображения в данные. Далее создается “отпечаток лица (faceprint)”, каждый такой отпечаток обычно уникален подобно отпечатку пальца.
-
Поиск совпадений. Далее производится поиск совпадений с уже известными отпечатками лиц. В такой базе хранятся идентификаторами, которые можно сравнить.
Где используется распознавание лиц
Технологии распознавания лиц применяются в самых разнообразных сферах:
- обеспечение безопасности в местах большого скопления людей;
- системы охраны, избежание незаконного проникновения на территорию объекта, поиск злоумышленников;
- фейс-контроль в сегменте общепита и развлечений, поиск подозрительных и потенциально опасных посетителей;
- верификация банковских карт;
- онлайн-платежи;
- контекстная реклама, цифровой маркетинг, Intelligent Signage и Digital Signage;
- фототехника;
- криминалистика;
- телеконференции;
- мобильные приложения;
- поиск фото в больших базах фотоснимков;
- отметка людей на фото в социальных сетях и многие другие.
Заключение
В данной работе мы рассмотрели теоретическое обоснование реализации программного обеспечения роботизированных систем. Затронули понятие жизненного цикла проекта, упомянули распространенные архитектурные проблемы и их решение. Провели сравнение микросервисной архитектуры с монолитной и привели аргументы в пользу первой для реализации нашего проекта. Также был упомянут принцип сингулярности микросервиса, где мы рассмотрели возможность обобщения архитектуры для любого микросервиса и определили минимальную реализацию микросервиса. Во второй части работы мы рассмотрели из чего в теории может состоять микросервис и что необходимо для автономной работы в качестве полноценного сервиса. В заключение была рассмотрена реализация сервиса распознавания лиц.
Список литературы
-
Ньюмен С. Создание микросервисов. СПб.: Питер, 2016. 304 с. ↩︎
-
Microservice Architecture [Электронный ресурс]. Режим доступа: http://microservices.io/. Дата доступа: 30.01.2017. ↩︎
-
Цитульский А.М., Иванников А.В., Рогов И.С. Интеллектуальный анализ текста. Научно-образовательный журнал для студентов и преподавателей «StudNet». 2020;6:476–483. ↩︎
-
Масштабируя до 100 миллионов: архитектура, определяемая уровнем сервиса [Электронный ресурс] – Режим доступа – URL:https://habr.com/company/wix/blog/282045/ (Дата обращения 15.05.2022) ↩︎
-
Никитин И.В., Гриценко Т.Ю. Сравнение подходов монолитной архитектуры и микросервисной архитектуры при реализации серверной части веб-приложения // Дневник науки. 2020.№ 3. ↩︎
-
Микросервисы: размер имеет значение, даже если у вас Kubernetes[Электронный ресурс]. – Режим доступа – URL:https://habr.com/company/flant/blog/424531/ (Дата обращения 15.05.2022) ↩︎
-
Мартин Р. Чистая архитектура. Искусство разработки программного обеспечения. СПБ.: Питер, 2018. ↩︎
-
Гагарина Л. Г., Кокорева Е. В., Виснадул Б. Д. Технология разработки программного обеспечения : учеб. пособие. М. : Форум Инфра-М, 2013. 400 с. ↩︎
-
A.J. Goldstein, L.D. Harmon, A.B.Lesk, “Identification of Human Faces”, Proc. IEEE, May 1971, Vol. 59, No. 5, 748-760. ↩︎
-
M.A. Turk and A.P. Pentland, “Face Recognizing Using Eigenfaces”, Proc. IEEE, 1991, 586-591. ↩︎
-
P. Viola and M.J. Jones, «Rapid Object Detection using a Boosted Cascade of Simple Features», proceedings IEEE Conf. on Computer Vision and Pattern Recognition (CVPR 2001), 2001. ↩︎
Комментарии