Микросервисы: LAN
Теория и практика | создано: 16.03.2020 | опубликовано: 17.03.2020 | обновлено: 13.01.2024 | просмотров: 2353
Микросервисная архитектура - понятие размытое и не имеет чётких рамок. Есть только набор некоторых абстрактных характеристик, которые в некоторых случаях могут даже противоречить друг другу. В этой статье будем разбираться с микросервисной архитектурой для корпоративных сетей. В этом видео про: архитектура, микросервисы, lan, wan, UI-клиент, backend, frontend
Какие бывают сети
Микросервисы работают в сети. А какие бывают сети? Давайте посмотрим, что на эту тему есть в интернете (wikipedia):
- Глобальные сети - WAN. (интернет)
- Metropolitan Area Networks (MAN).
- Корпоративные (сети организаций, предприятий) - Enterprise Wide Networks(EWN).
- Локальные - Local Area Networks (LAN).
- Персональные - Personal Area Networks (PAN).
На мой взгляд, можно объединить некоторые пункты по типу подключения к сети и/или по протоколу передачи данных. Первый тип WAN - это интернет, то есть протокол взамодействия является HTTP и принцип подключения глобальная сеть, где компьютеры выходять в сеть через провайдера интернета. Остальные в этом списке, так или иначе, являются корпоративным (локальным) типом, потому что подключение происходит по "локальной сети" по протоколу TCP/IP, с авторизацией на сервере компании (например, на сервере со службой Acrive Directory) или на каком-нибудь другом выделенном сервере, который "обслуживает" частную локальную сеть. Итак, давайте выделим два типа, для которых может быть поставлена задачи реализации микросервисной архитектуры: глобальная сеть и корпоративная сеть. В этой связи возникает вопрос: одинковы ли принципы построения микросервисной архитектуры для этих двух типов? Если с глобальной всё или почти всё понятно, то про корпоративную надо поговорить.
Микросервисы: Корпоративная сеть
Давайте разбираться. В большенстве случаев, когда разработчики говорят о микросервисной архитектуре речь идет о серверной стороне, то есть об API (backend). Но некоторые склонны называть UI-клиенты также микросервисами, хотя концептуально это неправильно. В книге Роберта Мартина "Чистая архитектура" есть глава "О вводе и выводе", где можно прочитать, что:
О вводе и выводе
Разработчики и клиенты часто неправильно понимают, что такое система. Они видят графический интерфейс и думают, что он и есть система. Они определяют систему в терминах графического интерфейса и считают, что
должны сразу начать работу с графическим интерфейсом. Они не понимают важнейшего принципа: ввод/вывод не важен.
Другими словами, UI-клиентов может быть сколь угодно, которые могут работать с бизнес-логикой, и эти самые UI-клиенты зависимы от backend. Под словом "backend" я подразумеваю бизнес-логику. следовательно считать UI-клиентов микросервисами, на мой взгляд, это заблуждение. Но, как ни крути, UI-клиенты не могут не быть частью микросервисной архитектуры. Backend без клиента - не имеет смысла. А дальше - давайте посмотрим на картинки.
Глобальная
Все клиент подключены к сети через провайдера (в нашем случае, напрямую). Клиентом для работы с микросервисами является с любой браузер - как самый простой и дешевый способ подключения (я намеренно не говорю про специализированные программы).
Корпоративная
В корпоративной сети дела обстоят немного по-другому. Есть "главный" компьютер (или даже несколько), который управляет пользователями и разрешениями для них. Все пользователи могут подключаться к сети микросервисов также через браузер, но есть еще одна приятная "мелочь" - локальная сеть (LAN), которая тоже может быть использована как транспорт для работы с микросервисами. Скажу наперед, LAN предпочтительнее во всех отношениях. Но об этом позже.
Итак мы определили, что есть некоторые топологические отличия сетей, а значит это не может не повлиять на реализацию микросервисной архитектуры.
Немного истории
Когда-то разработчики видели приложения в таком формате. Мы не будем говорить о двух- и трехзвенной архитектуре, это тема другого урока. Мы просто поглядим на абстрактную модель.
То есть, существовала база данных и для доступа к ней создавалось приложение. Потом произошла некоторая трансформация и приложение разделилось на две части: backend и frontend
Другими словами, произошло отделение UI представления от бизнес-логики. Это чётко наблюдалось, например, в ASP.NET MVC или в WPF (MVVM). Прогресс не остановить и после этого появилось понятие "микросервисы", и тогда деление на модули (микросервисы) приняло примерно такой вид:
Где каждый сервис имеет свою базу данных и имеет свой набор бизнес-логики. По словам Мартина Фаулера: "smart endpoints and dumb pipes". Что в вольном переводе может звучать как "Умные оконечные точки (сервисы) и тупые трубы".
Frontend
Если с backend реализацией микросервисной архитектурые более или менее всё понятно (если не всё понятно), то некоторые вопросы относительно frontend еще остаются открытыми.
Микросервисы уверенно "шагают" по миру, всё больше и больше "монолитов" трансформируются в микросервисы. Но что же случилось с frontend? Почему не трансформируется эта часть архитектуры? И это есть проблема. Эту проблему называют "Microservices Last Mile problem". В данном контексте "last mile" относится именно к доставке контента до конечного потребителя программного обеспечения. Казалось бы, бери Single Page Application и пиши приложение, какие могут быть сомнения. Но это на первый взгляд. Именно при разработки frontend для микросервисной архитектуре в процессе разработки появляются подводные камни. И если вы выберите Single Page Application (причем не важно на каком spa-фреймворке) - эти проблемы вам придется решать!
Вы спросите, какие проблемы? Давайте о них...
Одно из определений микросервисной архитектуры гласит о том, что может быть использован любой стек и любая платформа. Предположим, у вас есть некоторое количество SPA приложений для ваших конкретных API, которые написаны на разных UI-фреймворках. Потому что работали разные команды разработчиков, которые просто решили использовать тот, что лучше всего знают.
Хорошо если решили использовать один и тот же UI-фреймворк, иначе плюсом к проблемам добавятся разные версии одних и тех же фреймворком. На одном сервисе вы успели обновить, на другом нет. Так бывает, просто поверьте.
А теперь перед вами, как перед главным архитектором вашей компании, встает задача - показать все сервисы в одном проекте (объединить и тем самым предоставить пользователю доступ к системе из одного места). Во-первых, "бизнес" имеет на это право. Во-вторых, почему и нет? Сделать пользователям приямно и объединить все ваши микросервисы в одно приложение, чтобы было удобнее. Другими словами, сделать что-то на подобие dashboard или shell. Ключевыми требованиями можно считать:
- динамическое меню, которое базируется на ролях пользователей;
- обособленное обновление и публикация сервисов должны остаться;
- один раз вход на сайте, а не во все сервисы отдельно;
- одинаковый корпоративный стиль компонентов
- и прочие, прочие, прочие "монолитные хотелки"
Есть решения
Мир не без добрых людей. Например, Мартин Фаулер описывает один из вариантов решения как Micro Frontends. Описание слишком абстракно, но если углубляться в детали, то можно сказать, что оно построено вокруг Web Components. В многих фреймворках для UI есть реализация данного подхода.
Но данный подход решает далеко не все проблемы. И к тому же, данный подход накладывает кучу ограничений и придется решать множество других проблем, например:
1. Ваши все UI-клиенты для ваших же микросервисов должны быть написаны на одном и том же фреймворке, в противном случае модули не соберутся в одно целое (или придется "допиливать" в "ручном режими процесс сращивания" ваших модулей). Тогда придется ограничиться тем, что каждый сервис имеет свой адрес, и тем самым заставлять пользователя метаться между закладками браузера. А "бизнес" может не пойти на такие ограничения.
2. Вам придется обновлять версии всех ваших UI-клиентов одномоментно, в противном случае вы придете к тому, что функционал перестал работать. А если не обновляться, ваши проекты быстро превратятся в legacy-код. Ну, и опять же, вы потеряете одну из "фишечек" микросервисной архитектуры - обособленно обновление и deploy. То, что сервисы могут публиковаться обособленно не значит, что они не связаны между собой архитектурно.
Надо сказать, что описанные выше проблемы распространяются на оба типа сетей, и на глобальной, и на корпоративной.
Я не могу "показать пальцем" на решение, какой-либо фреймворк или nuget-сборку, которая приведет вас "к победе" над всеми проблемами. Реализация микросервисной архитектуры зависит от множества факторов. И они на столько индивидуальны, что универсального решения не существует.
К сожалению
К сожалению, на этом проблемы не кончаются. Если говорить про корпоративную реализацию микросервисной архитектуры, то возникают вопросы без решения которых вы не сможете двигаться дальше.
Основная проблема - браузер не имеет (простой) возможности (из соображения безопасности) «достучатся» до компьютера пользователя.
Следовательно, проблемы только начинаются…
Как получить из приложения SPA, то есть из браузера, доступ к подключенным к компьютеру устройствам? Без некоторых устройств пользователю вообще невозможно учавствовать в бизнес-процессах предприятия.
Например, флэш-диски, которые открывают доступ. Веб-камеры, фото с которых должно попасть в документы. В конце концов, просто принтеры, особенно в тех случаях, когда быстрая (прямая) печать имеет важное значение. А что говорить про более сложные устройства? Например, сканеры штрих-кодов? Смею вас заверить, что решения на базе SignalR и/или Windows Services только добавят проблем.
И как же быть?
Когда речь идет про "разбиение" монолита на микросервисы в этот момент мало кто задумывается про то, как это каснется клиентского приложения, особенно, когда речь идет о корпоративном подходе. На основании своего опыта могу сказать, что решение всё-таки есть.
Когда-то, очень давно, было модным разрабатывать программное обеспечение с использованием модулей (plugins). Да, да, да! Вы не ослышались, именно модули! Каждый модуль может иметь доступ к своему сервису или к нескольким. Суть сводится к написанию клиента на WPF или на WinFroms (всё-таки WPF лучше, по причине возможного использования MVVM). Если у вас есть несколько групп разработчиков, то каждая команда может писать код только для своего модуля, при этом используя некую общую оболочку (shell - относительно несложную по реализации) для тестирования и отладки). Распространение программы, так называемы LastMile - это банальная установка программы, или просто положите в папку главного компьютера и откройте доступ :). Обновление можно также через установку новой версии или реализовать собственные механизмы запроса версии на сервере и обновления программы.
"Хотелки" озученные выше реализуются "на ура!":
- Динамическое меню, которое базируется на ролях пользователей - каждый модуль "выставляет" наружу свои опции меню, которые "собирает" в кучу shell. Современные DI-контейнеры предоставляют данных функционал и могут это делать "из коробки".
- Обособленное обновление и публикация сервисов должны остаться - вам нужно просто положить обновленный модуль в нужную папку или настроить автоматический deploy при каждой компиляции. Это простой вариант для локальной сети, но есть еще куча других вариантов реализации обновления модулей. Локальная сеть + умный devops = чудеса!
- Один раз вход на сайте, а не во все сервисы отдельно - это также будет работать "из коробки". Токен полученный в shell - можно "передавать" во вложенные модули. При этом, если у вас нет прав на открытие модуля, то и прав для него не потребуются.
- Одинаковый корпоративный стиль компонентов - это будет реализовано само собой если не применять какие-либо стили. Да и стили в WPF можно будет использовать в модулях одинаковые, например через приватные nuget-сборки.
Итак, озвучу ключевые моменты реализации данного подхода:
- Оболочка (shell). WPF приложение как оболочка для других модулей. При этом подход MVVM (где можно использовать DI-контейнер с поддержкой модульности "из коробки")
- Вход в shell (авторизация) - единственное место для входа пользователя. Сработает даже принцип отзыва токена JWT (token revoke), потому что он в одном месте и достаточно его удалить из локального хранилища чтобы запретить доступ и заставить заново проходить авторизацию.
- Обновление модулей динамически. Можно в "ручном" или в автоматическом режиме.
- Вы получите доступ к устройствам, которые устновлены на вашем компьютере (в хорошем смысле). А значит вам станет доступна информация из корпоративной сети. Например, вы сможете моментально распечать файл (сгенерированный сервисом отчет) на принтер, которой у вас устновлен по умолчанию. Да что там "принтер"! Вы получите имя компьютера! :) Иногда это очень полезно знать для логирования!
- Централизованное обновление и Shell и модулей системы. Вариантов реализации обновления системы можно придумать и реализовать какие только захотите, и те, которые устроят только вас. Не говоря уже о том, что локальная сеть - это локальная сеть.
- Если в вашей огранизации используются только Windows системы, то вы можете использовать полноценный NET Framework. Если есть комьютеры с другой операционной системой - ничего нет невозможного для NET Core, потому что теперь эта платформа поддерживает WPF (начиная с версии 3.1 почти полноценно).
Заключение
Немного повторюсь... Разработка микросервисной архитектуры - это непростая задача, которая имеет много подводных камней. Нюансы реализации зависят от множества факторов. Универсального решения - нет. Разработка микросервисной архитектуры в качестве корпоративной системы - лишь добавляет требования, которые могут повлиять на архитектуру на столько, что придется ее пересматривать. А есть ли у "бизнеса" на это время?
В любом случае, разделение зависимостей (ответственности) надо делать очень осторожно, как на стороне backend так и на стороне frontend. И помните, что клиенты в микросервисной архитектуре могут быть не только приложения в стиле Single Page Application, то есть браузерные приложения. Правильно написанный клиент - это решение проблемы "microservices last mile".