Системный архитектор. Кто этот человек?

Для кого эта статья? Эта статья, также как и первая, рассчитана на людей, работающих в сфере ИТ.  Для разработчиков, тестировщиков, менеджеров разного уровня, аналитиков и т.д. Для расширения кругозора, она также может быть полезна и всем остальным, просто, чтобы иметь представление о том, чем занимается Системный Архитектор.  Пригодится материал и тем, кто планирует развитие своей профессиональной карьеры, и тем, кто выкладывает такого рода вакансию и ищет специалиста в команду.

Что еще? Думаю что надо как то договорится о подаче материала. Здесь, как и в первой статье, я рассмотрю конкретный пример из своей практики, который, как мне кажется, максимально точно иллюстрирует специфику работу данного специалиста. Как и раньше, в заключении, попробую ответить на следующие вопросы: кто такой Системный Архитектор, какими навыками должен обладать и т.д. Поехали?  

И последнее, думаю, надо представится. Меня зовут Владимир Воловиков. Опыт работы в сфере разработки программного обеспечения более 20 лет. В должности Системного архитектора и Программного архитектора, в общей сложности, более пяти лет. Имею четыре международных сертификата. Текущее место моей работы Системный архитектор, Банк ВТБ. 

Ускорим работу

По каким принципам разбивают Монолит на Микросервисы? Вариантов много разных, но самый очевидный по бизнес возможностям. Начало моей работы над проектом, это начало работы над информационной системой, которая была выделена из Монолита в Микросервис по вышеуказанному принципу. Ну, и конечно, если бы работа была сделана удачно, то и делать тут Системному архитектору было бы нечего. Но, как правило, это не так. 

Чтобы продолжить, нужно читателю дать понять, что значит «удачно». «Удачно» — это значит, что новая информационная система удовлетворяет всем заранее оговоренным атрибутам качества. Атрибутов качества много разных, но есть два базовых атрибута — это надежность и производительность. Что такое надежность? Это в общем-то вероятность работы вашей системы в случае различных нештатных ситуаций. Выключили свет, нет связи, пожар, землетрясение и т.д. Проектирование высоконадежных систем, это в первую очередь все возможное резервирование: основная база данных, реплика, избыточность в рамках одного ЦОД, автоматическая система переключения основной базы данных на резервную, геораспределение и т.д. Все это было сделано, поэтому, эту часть я пропущу и перейду к производительности.

Производительность — это, то, какую нагрузку может выдержать ваш сервис. Какое количество запросов в секунду может обработать с надлежащей скоростью.  И вот тут возникают вопросы. Дело в том, что при некоторых сценариях, производительность не удовлетворяет потребителей. А потребители кто?

Оказывается у вновь разрабатываемой системы два абсолютно разных потребителя. Первый потребитель это человек, пользователь. Это различные «фронт» приложения. Нагрузка 1–2 запроса в секунду максимум. А второй потребитель — это внутренние информационные системы. И вот, как раз во втором случае, производительность системы оказывается недостаточной. В данном сценарии нагрузка может достигать 100 и более запросов в секунду. Скорость ответа варьируется от 0,8 до 2 секунд. И что тут такого? Ну 2 секунды, не 20-ть. Что тут может не удовлетворять потребителя?  

Чтобы читатель смог понять глубину проблемы, сделаю еще одно отступление. Представьте себе монолит. Представьте себе, например, интернет магазин и некий сценарий оплаты, который состоит из следующих этапов:  

  • проверка наличие товара в конкретном магазине;

  • списание средств с карты пользователя;

  • резервирование товара;

Если бы мы писали программный код, как бы это все могло выглядеть?

if (Goods.available(shopId, userGoodsSelectedList)) {
  if (PaymentCard.getMoney(totalUserGoodsCost)) {
    if (Storage.reserved(shopId, userGoodsSelectedList )  {
      Response.send(INFO.GOODS_RESERVER);
    } else {
      Response.send(ERROR.GOODS_RESERVED);
   }
  } else {
    Response.send(ERROR.GET_MONEY);
 }
} else {
  Response.send(ERROR.GOODS_AVAILABLE);
}

Мы видим три сущности: Goods, Payment, Storage. Каждая сущность имеет свои инкапсулированные  методы и свойства. Как быстро все это будет работать?   Да, мгновенно! Этот код весь  в памяти. А теперь, давайте, сделаем из этого микросервисы. Разделим их по бизнес возможностям

image-loader.svg

Goods, Payments, Storage и PaymentsController — все это микросервисы, которые взаимодействуют друг с другом через HTTP интерфейс. Очевидно, что это медленнее, чем в случае с Монолитом. Уже есть накладные расходы. А что, если у нас взаимодействие не параллельное, как на схеме выше? Что если сервис, Goods, получив запрос от PaymentController, делает еще ряд таких же интеграционных запросов, например, получает дополнительную информацию о пользователях. Что если второй сервис, делает также запрос в некую третью систему. Сколько времени в целом будет затрачено на операцию? Пусть даже все блоки отработали со скоростью 0,5 мс. Три системы, умножив на 0,5 получаем 1,5 секунды. И вот в этой цепочке, кто-то решил, что может работать две секунды. «Ни айс» :-)

Ну, что ж? Видим проблему, понимаем, откуда она взялась. Самое время заняться проектирование системной архитектуры. Дано:

Разделим «монолитный» микросервис на две части. Сделаем Микросервис для работы с внутренними потребителями и Микросервис для работы с внешними потребителями

Следующим шагом, нужно избавится или максимально исключить, количество интеграций в Микросервисе для внутреннего Потребителя. Вариантов тут два:

Что такое Бизнес-правила? Это, по сути, занесенные на бумагу правила, по которым работает бизнес. Это то, что отвечает на вопрос:»Почему именно так работает, а не иначе?». Приведу пример нескольких таких правил в разрезе нашего магазина

Номер

Описание

БП1

Для оформления заказа клиенту, сначала, необходимо произвести проверку наличия товара в указанном магазине, и только после нужно списать средства с карточки клиента и маркировать товар, как зарезервированный 

БП2

Как только товар зарезервирован, необходимо отправить уведомление Менеджеру и Клиенту

БП3

Менеджер, получив уведомление о том, что Клиент зарезервировал товар, должен внести в График Доставки зарезервированный товар

БП4

Зарезервированный товар должен быть доставлен Клиенту не позднее, чем через 24 часа с момента резервирования

БП5

Функция формирования Графика Доставки зарезервированного товара должна быть доступна сотруднику с более высокой компетенцией и ответственностью

Изменение любого пункта из данного списка автоматически влияет на всю логику работы системы. Упростив БП1, вы автоматически уменьшите количество интеграций и, как следствие, система будет работать быстрей. Упростив БП5, ваша система будет проще. Не нужны будут ни какие Ролевые модели, создание AD групп и интеграций с этим сервисом. Будет работать надежнее.

image-loader.svg

Отлично. Мы изучили Бизнес-правила, и одно из них нам удалось упростить. Результат — на одну интеграцию стало меньше. Что будем делать с двумя оставшимися?   

Что, если мы данные, за которыми ходим в эти сервисы, поместим к себе, внутрь нашего Микросервиса? В этом случае, делать интеграционные запросы нам уже будет не надо. Все будет у нас. Цена — избыточность информации. Мы ее понимаем и принимаем. Но как быть в случае, если информация изменится? У нас-то она останется старой. Нужна синхронизация. Давайте, попробуем рассмотреть различные варианты решения этого вопроса:

  1. Интервальная синхронизация. Периодически, допустим, раз в сутки, производить запросы к Поставщикам информации и обновлять локальные данные.

  2. Попросить Поставщиков информации отправлять нам уведомление о том, что информация изменилась.

В первом варианте, очевидно, что наша система будет производить неактуальные действия, основываясь на устаревшей информацией. Хорошо ли это? Системный архитектор не может на это ответить, ответ есть у бизнеса, и выглядит он как формирование и внедрение  нового бизнес-правила. Принятие его. Например, вот такого

Номер

Описание

БП6

После изменения свойств товара оператором, изменение этих свойств на сайте должно появится не позднее 24 часов

Для реализации второго варианта, необходима доработка и нашего Микросервиса, и, возможно, сервиса Поставщика. Необходимо внедрение в архитектуру Шины Событий: Kafka, RabbitMQ и т.д. 

В итоге, пусть один из наших сервисов, по разным причинам, не может работать с Шиной событий, а другой может. Итоговая картина будет выглядеть так как рисунке ниже

image-loader.svg

Теперь посмотрим на Базу данных. Что было, что стало? Идеология проектирования Микросервисов, это идеология инкапсулирования в одном месте логики, данных и команды. Изолированная зона ответственности. Давайте мысленно вспомним, что происходило с данными в результате наших манипуляций проделанных ранее

  1. Единый Микросервис-монолит мы разбили на две части

  2. Для каждого нового Микросервиса, мы выделили отдельную базу данных, по сути, сделав две ее копии

  3. Базу данных Микросервиса для внутреннего потребления мы дополнили двумя таблицами: Данные от поставщика 1 и Данные от поставщика 2

image-loader.svg

Давайте, попробуем нарисовать Диаграмму сущностей и отношений опять же в разрезе нашего выдуманного интернет-магазина. Как было и как стало?  

Было 

image-loader.svg

Стало, после разделения «монолитного» микросервиса на два

image-loader.svg

Стало, после добавление новых таблиц и уменьшения количества интеграций

image-loader.svg

Смотрим на то, что получилось и плачем. Решив одну проблему, мы породили целый ворох новых

  • Рассогласованность данных. Данные у Микросервиса для внешнего потребителя  отличаются от данных у Микросервиса для внутреннего потребителя 

  • Избыточность данных: по сути, две копии одного и того же

  • Отсутствует единый источник правды 

Очевидно, что с таким багажом далеко не уедешь. Что то надо с этим делать? Вероятно, стоит попробовать перечислить все возможные варианты решения, дать оценку —  поможет ли это в решении выявленных нами проблем или нет.

Физическая репликация

Первая идея состоит в том, чтобы настроить наши базы данных так, чтобы изменения данных в базе данных Микросервиса для внешнего потребителя, автоматические попадали в базу данных Микросервиса для внутреннего потребителя. Делается это  настройками базы данных. Это отличное, простое и надежное решение, но это не наш случай. Наши базы данных отличаются друг от друга. Физическая репликация, это все же инструмент для организации надежности.

Логическая репликация триггерами

Вторая идея  заключается в том, чтобы написать Триггер — хранимую процедуру. Триггеру, который вызывается при изменении каждой записи, доступно ключ этой записи, а также новое и старое значение. При необходимости триггер может сохранять новые значения строк в специальную таблицу, откуда специальный процесс на стороне реплики будет их вычитывать. В целом выглядит неплохо, но избыточность осталось. Плюс, какая-то сложность в разработке и отладке, возможно, есть варианты проще?  

Прикладная репликация

Третья идея заключается в том, чтобы использовать уже заложенную в архитектуру шину событий. Сервер приложений Микросервиса для внешнего потребителя, после сохранения данных в своей базе данных, отправляет событие с данными через шину. Сервер приложений Микросервиса для внутреннего потребителя получает это уведомление и вносит изменение в свою базу данных. Тут тоже, как и в случае, с Логической репликацией триггерами присутствует избыточность и также есть какая-то дополнительная сложность в разработке. Более того, в случае, если кто-то сделает изменения прямо в базе, выполнив запрос, то синхронизации не будет. Это тоже нужно учитывать. 

Схема с Прикладной репликацией с использованием шины данныхСхема с Прикладной репликацией с использованием шины данных

Общая база данных

И последняя идея заключается в том, чтобы сделать единую, общую базу данных для обоих наших микросервисов. Просто консолидировать ресурсы в одном месте.  В некоторых случаях, это считается Антипаттерном, потому что противоречит основному принципу микросервисной архитектуре, а именно, инкапсуляции данных, ресурсов и т.д. в одном месте, в одной команде. В случае, если у нас два микросервиса разрабатываются двумя разными командами, но при этом, у них одна общая база данных, то автоматически возникают коллизии. Внесение изменения в эту базу, в ее структуру, будет также влиять на вторую команду. Но у нас одна команда и таких коллизий не будет, поэтому для нас это оптимальный вариант.

Итоговый вариант архитектуры ИСИтоговый вариант архитектуры ИС

Подведем итоги

Кто такой Системный архитектор?

Это специалист, который занимается проектированием архитектуры системы в целом для того, чтобы система могла обеспечить целевые показатели качества. Системный архитектор — специалист, способными вывести компанию на новый уровень бизнеса, выигрывать конкуренцию за счет разумного подхода и реинжиниринга процесса разработки.

Чем отличается Программный архитектор от Системного?

Область работы Программного архитектора — это программный код. Работа над архитектурой программного кода для того, чтобы работать над ним командой было просто. Для того, чтобы его можно было масштабировать и легко поддерживать. Системный архитектор, это, по сути, ступень выше. Системный архитектор манипулирует набором программных продуктов, в том числе, и системой, которую разработал Программный архитектор, как неким блоком, блоком, который выполняет определенную функцию. Комбинируя такие блоки, Системный архитектор строит информационную систему, которая способна выполнять бизнес-требования и соответствует нужным атрибутам качества. 

Должен ли уметь программировать Системный архитектор?

Теоретически — нет.  Путей ведущих к этой должности несколько. Одна из них через бизнес-аналитику. Другая — путь программиста. Может быть также путь Системного администратора. Но я лично не встречал Системного Архитектора, который не умел программировать или не программировал раньше.

Какими навыками должен обладать Системный архитектор?

Как бизнес аналитику, ему необходимо:

  1. уметь внятно и точно выразить свои мысли

  2. переложить их на бумагу

  3. владеть несколькими UML нотациями, например, Диаграмма классов (Class Diagram) и Диаграмма деятельности (Activity Diagram), диаграмма последовательностей Sequence диаграмма. Возможно, также пригодиться Event Storming диаграмма 

  4. уметь выявлять бизнес правила (требования)

Как архитектору

  1. SOAP, REST, GRPC и т.д. Какие виды протоколов взаимодействия есть между системами. Плюсы, минусы, опыт работы с ними

  2. Различные шины данных. Кеши и т.д. Также плюсы, минусы их

  3. Какие базы данных существуют? Какие задачи решают? Репликация, шардирование и т.д.

  4. Схемы построения надежности баз данных

  5. Схема построения высоконагруженных систем

Сколько лет должно быть практики, чтобы быть Системным архитектором?

Если открыть список навыков, что был мной составлен на позицию Программного архитектора, то может показаться, что там список будет поболее. Но это только на первый взгляд. Системный архитектор — это опыт. С каким количеством баз данных вы работали? С какими протоколами? И если какие то навыки программный архитектор может получить самостоятельно, развернув один — два проекта, то развернуть экосистему с массой различных элементов, различных баз данных, различных протоколов, просто невозможно. Так сколько лет должно быть практики у Системного архитектора? Я бы смело добавил лет пять к тем значениям, что получились у Программного архитектора.

Заключение

Системный архитектор, это, безусловно, топ технической специальности. Это опыт, опыт и опыт. Это очень большой кругозор. И это уже конечно хорошо развитые «софт»- скилы. Без них уже никак. Как и что должно работать? Какие взаимодействия? Какая реакция системы? Как бизнес требования переложить в систему? Все это непростые навыки, развить которые, увы, невозможно ни на каких курсах

За помощь в подготовке данной статьи автор благодарит Балахчи Анну Георгиевну, Иркутский Государственный Университет, Факультет Бизнес-коммуникаций и информатики, зав.кафедры, кандидат физико-математических наук

© Habrahabr.ru