Для понимания того, чем мы тут занимаемся обязательно прочтите предыдущую статью:
Часть 1 (Про что статья + проверяем Monolith)
Вводная
Добрый день снова, дорогие читатели!
В продолжение первой части мы сегодня будем снова пробовать разные Архитектурные стили и сегодня мы переместимся с Монолита на Сервисо‑ориентированную архитектуру (Service‑Oriented Architecture или SOA) на движке Factorio. Наконец‑то мы не просто соберём данные, но ещё сравним их с нашим предыдущим замером различных параметров — с Monolith.
Наконец‑то мы узнаем, какие преимущества имеет первый и второй стиль. И это только начало!
С этого момента я начну писать название Архитектурных стиле на английском языке, чтобы их можно было легко глазами выискивать в тексте и ещё избавиться от двузначности терминов.
Начнём!
Сервисно‑ориентированная архитектура (Service‑Oriented Architecture или SOA)
Немного вспомним, чем интересен данный архитектурный стиль.
Именно в нём начались первые попытки разбивать запутанные, монолитные приложения по программной логике: какой‑то сервис занимается фронтом, другой считает деньги, третий организовывает хранение файлов и так далее. Чтобы всё это работало относительно независимо друг другу, придумали всё соединять некой шиной — Enterprise Service Bus (далее просто «Шина»). Именно эта шина содержала в себе логику «что, куда и при каких условиях отправлять», а при этом остальные Сервисы просто принимают от шины запросы, обрабатывают их и возвращают обратно в шину.

Самое основное, что тут хотели добиться — это независимого развития/обновления отдельных Сервисов. То есть мы технически можем донести в приложение один обновлённый Сервис, не пересобирая/перезапуская всё приложение целиком.
На бумаге это выглядит так, что на каждый сервис можно назначить определённую команду программистов и они будут писать код под стандарты Шины не отвлекаясь на то, то твориться в соседних командах/сервисах.
Сама Шина технически (то есть «грубо говоря») тоже является сервисом — то есть там есть своя программная логика и команда программистов, которую её поддерживают. Но никакой Бизнес‑логики она не выполнят, а занимается только сервисной работой по приёму/передачи запросов из одного Сервиса в другой. Поэтому не представляйте себе Шину как какой‑нибудь протокол передачи типа REST — это уже тогда другая архитектура получится. Ну и все прочие Сервисы обязаны работать по стандартам этой шины: получать от неё запросы, обрабатывать и возвращать результат обратно в шину. И никак иначе.
Если углубится в Интернет за поиском дополнительной информации по этой архитектуре, то можно увидеть по ней есть прямо множество статей, но при этом все этот стиль не рекомендуют к применению. А причина проста — она содержала кучу критически важных минусов для приложения. При этом популярность её обусловлено тем, что именно она дала толчок для развития в сторону других Архитектурных стилей (Service‑Based, Space‑Based, Event‑Driven и Microservices), которые мы ещё рассмотрим в будущем.
У SOA выделяют один существенный недостаток — непропорционально нарастающая сложность логики в Шине. То есть когда приложение будет расширяться, всё больше и больше логики «что‑куда‑когда» будет заноситься в Шину, а поскольку она является критическим, связующим звеном для всех Сервисов — ошибка в ней чревата сбоями в работе приложении. Плюс к командам разработки отдельных Сервисов ещё появляется необходимость плотного общения и с командой разработки Шины: согласовать маршруты, дождаться его реализации, отладить/проверить этот маршрут и пр. А ровно это общение идти некогда не будет: что‑то не туда настроили в шине; что‑то соседнее сломали по ходу настройки; что‑то хотели уникального для своего Сервиса, но не получилось договориться и так далее. А ещё и команда разработки Шины вполне может себя почувствовать привилегированной — на ней держится всё приложение и отдельные пожелания других Сервисов её могут не волновать годами. В общем, именно на этом аспекте и не удалось получить от Архитектурного стиля ни ускорения разработки, ни надёжности.
Когда мы будем пробовать смастерить эту архитектуру в Factorio, мы должны будем наткнуться на ту же проблему — поддержка Шины должна будет потреблять достаточно большую долю человекочасов разработки продукта. Если это будет так и у нас — значит мы реализуем нечто похоже на то, что было в реальных приложениях на SOA‑архитектуре. Хотя ещё на этапе начала становится понятно, что мне вряд ли получится в игре смоделировать всю «прелесть» взаимодействия шины, но я буду пытаться.
Предварительный план
Давайте сразу же определим основные аспекты Стиля и попробуем перевести это в игру до её начала.

Во‑первых, не смотря на то, что SOA поддерживает любой протокол доставки взаимодействия между сервисом и Шиной, я всё же остановлюсь на конвейерах. Просто потому‑что будет странно организовывать поезда на коротком маршруте до Шины, а в игре других альтернатив особо и нет. Так что представим, что у нас приложение расположено на одном физическом узле и общаются они через сокеты. На этом и остановимся.
Во‑вторых, пользователи всё так же будут приходить к нам в приложения по ЖД (то есть по сети). И как и в Monolith'е, в SOA это должно быть единственное использование ЖД во всём продукте.
В‑третьих, ни в коем случае нельзя смешивать производства, как это было в Monolith'е — если уж ответвились для создания, например, Зелёных Микросхем, то только для Зелёных Микросхем эта ветка и предназначена. А дублировать одинаковые производства можно — считаем это вертикальным масштабированием.
В‑четвёртых, электростанция тоже будет частью одной из веток Шины. Но она будет только потреблять ресурсы с Шины, а не отдавать (электричество особо на конвейер не положишь).
В‑пятых, трубы с жидкостями так же придётся вести по Шине.
В‑шестых, конвейера в Шине должны будут двигаться в обе стороны так как ряд сырья будет требоваться не только впереди по заводу, но и сзади (например, то же ядерное топливо из середины Шины придётся вести к электростанции, располагаемой в самом начале).
В целом всё. На данный момент я вижу тут две сложности и одну легкость:
Первая сложность — я не представляю, как будет работать Шина и насколько сложно/возможно будет её обслуживать;
Вторая сложность — из‑за всё той же Шины весь завод будет занимать кучу места, на что достаточно скоро сагрятся жуки;
Легкость — вертикально расти при такой схеме будет значительно проще. Главное оставлять пространство между ответвлениями от Шины.
Пока же я набросал следующую схему Шины:

В теории всё выглядит хорошо: заводы будут расширятся условно бесконечно вниз, а Шина расширяется условно бесконечно вправо и, чуть медленней, вверх. Даже есть место чтобы развернуть некоторые конвейера в случае необходимости (наверное).
Но опять же — это всё прототип, а игра не так проста и в ней явно возникнут сложности ближе ко второй половине игры. По сути тут нужно будет всегда соблюдать правило «не тулить» и оставлять место как между ветками, так и в самой Шине. Ну и нужно будет ОЧЕНЬ много конвейеров и труб...
В общем, думаю, что можно пробовать начинать...
Старт игры. Пилот
Для того, чтобы обеспечить постройку самой Шины, подключить всё к ней и при этом не испытывать проблем со стройматериалами — я в первую очередь наладил производство базовых предметов (конвейеров, заводов, манипуляторов, печей и так далее). Для этого я по‑быстрому создал небольшой заводик прямо возле ископаемых ресурсов и сделал там по примеру прошлого захода — Monolith'а. Как выяснилось, это было удачным решением так как предметы на Шину расходуются крайне быстро и стартового набора не хватило бы даже на то, чтобы создать самые первые производства.
Ну и для науки: видимо отныне все Архитектурные стили всегда придётся начинать с мини‑Monolith'а. Это даже чем‑то напоминает на MVP.
В целом мой план работает хорошо: сначала я подключил переплавку ресурсов, потом перенёс электростанцию в начало, ну и продолжил создавать различные зоны производства (шестерёнки, колбы и так далее). Пока всё это хорошо расширяется — заводы можно расширять вниз, а Шину — вправо. А если будет достигнут лимит по расширению завода — никаких проблем не будет сделать ещё одну зону с аналогичным производством далее по Шине.

Пока я делал это всё, меня не покидало желание экономить — то расположить завод теснее, чтобы позже добраться до жуков; то сделать поменьше ширину канала в Шине. Оно и верно — по ощущениям на создание Шины и подключения к ней уходит неприятно много времени, а предметов на конвейере пока не много. В общем, это именно то, с чем приходится морально бороться с собой и не допускать подобные мысли.

Чуть позже у меня нарисовались две проблемы:
Во‑первых, у меня меня достаточно быстро истощились стартовые рудник железа, меди и камня, а до ЖД было ещё далеко (я даже не успел наладить производство Зелёных микросхем для Зелёных колб). В итоге пришлось временно тащить пару путей из конвейеров от ближайшей жилы. Когда у меня будет ЖД — я переведу этот костыль на поезда, но пока только так. Относительно Продукта это означает что мы начали не укладываться в Сроки — вместо того, чтобы полноценно впустить пользователей мы всё ещё работаем с ограниченным числом пользователей. То есть у нас происходит что‑то вроде закрытого Альфа‑тестирования, но при этом приложение готово взять и бóльшую нагрузку — странная ситуация.
Во‑вторых, я территориально разросся так, что уже начал подходить к месту дислокации Жуков. То есть мы ещё в добавок начали выходить за Бюджет. Поскольку скоро начнутся нападения (ака нападки Бизнеса на неукладывание в бюджет), я прервал наладку производства Зеленых колб и сконцентрировался на производстве оборонительных сооружений (стены, турели и патроны к ним) и Чёрных колб. На текущем этапе игры убивать их ульи крайне сложно — у меня открыто не так много исследований на военное дело, а воюю уже со Средними червями. В общем, когда «Бизнес» начинает давить на проект в плане затрат — начинается крайне нервная работа в пустую по обоснованию Сроков и Бюджета. Позже, с увеличенным уроном и гранатами, уничтожать ульи стало легче, но всё это всё равно на это потратился достаточно ощутимый процент общего времени, которое можно было бы потратить на движение по пути полноценного старта работы пользователей.

В общем, всё плохо.
Зато я, как ни странно, я не испытываю проблем с Конвейерами: как только я наладил производство Желтых Конвейеров оказалось, что их производственных мощностей хватает для поддержки как Шины, так и Завода в целом (если помните, в Monolith'е с этим были большие проблемы). В общем, как ни крути, Архитектура медленно и верно начинает себя окупать.
Сама Шина уже начинает разрастаться так, что её становится проблемно обслуживать — даже её план уже в экран не помещается. Пришлось снова чуть‑чуть отвлечься от ЖД и сделать производство радаров — расставив их, смог удобней работать с картой и с разросшейся Шиной стало проще.
Ещё очень много тратится времени на расположение, строительство и подключение Шины. При этом полностью воспользоваться вместимостью этой Шины так и не смог — по её широким каналам перемещаются тонкие ручьи предметов и только в где‑то в конце оно накапливается в ожидании потребления...

Ну а спустя некоторое время я вообще упёрся в большое озеро по пути хода Шины и пришлось ещё раз отвлекаться на производство земли для отсыпки территории.

В общем, одни проблемы и я не представляю, как это всё можно было бы предугадать на первоначальном этапе планирования работы с SOA. Уже прошли игровые сутки, а я даже не успел поставить производство предметов для запуска ЖД (напомню, что в Monolith'е к суткам игры мы уже завершили игру).
И ещё отмечу один минус: всё это очень трудозатратно по предметам, по территории и по времени — бюджет на разработку явно раздуется на всё это безобразие, а начало получения прибыли всё откладывается и откладывается...
Из хорошего могу отметить следующее:
Расширять Шину и подключать к ней заводы оказалось достаточно просто, хоть и долго — по сути работает принцип копировать‑вставить и дальше начинают работать дроны. Короче, достаточно монотонная работа;
Затыков на Шине нет — все ресурсы поступают вполне себе равномерно и есть ещё много места для роста;
Шину не обязательно прямо всегда строить, тратя конвейеры — редко используемые потоки ресурсов можно не вести вперёд до востребования, однако нужно не забывать всегда оставлять под них места в Шине.
Обрастание фичами
ЖД наконец‑то подключено — железо, медь и уголь полились рекой.

Уже сейчас можно заметить, что всё развитие продукта движется крайне медленно: если в Monolith'е основной проблемой было придумать как втулить то или иное запутанное производство, то здесь таких вопросов не возникает, но от этого времени и ресурсов уходит далеко не меньше.
Плюс возникает много смежных проблем: то начали кончатся конвейера для постройки Шины, то земля (пока строил на воде), то жуки вечно норовят прорвать оборону.
Ещё я заметил, что ресурсов как таковых у меня много, но вот они все застряли в неактуальных местах: то в самой Шине, то на не приоритетном производстве — в Monolith'е подобного у нас такого в подобных масштабах не наблюдалось. Зато если построить завод в текущем конце Шины, то все эти зависшие ресурсы из Шины идут именно на новое производство и мы на первое время получаем заметный прирост данный предметов. Из‑за этого на графиках всегда можно заметить пик производства в самом начале, а потом оно нормализуется.

Ещё странным выглядит подключение к Шине тех производств, которые не могут быть продолжены (например, Электрические столбы, Длинные манипуляторы, Ящики). У меня возникало куча вопросов вида «зачем они здесь, ведь оно не будет давать результата обратно в Шину»? Но правило есть правило.
Жуки прямо покоя не дают: вдалеке от центра их много и они хорошо защищены. И неизвестно, что с этим можно сделать: в Monolith'е удавалось с ними мало контактировать из‑за малого размера завода; в будущих Microservices'ах я предполагаю, что можно будет делать производства равномерно от центра. Но в SOA мы просто ведём Шину в одну сторону навстречу ульям на весь экран и Чудовищным червям.

Забавный случай произошёл с Шиной: когда я реализовал производство Синих колб я понял, что мне нужно будет везти их обратно в начало шины, где у меня располагаются Лаборатории. Но это оказалось не так просто так как, во‑первых, придётся вести достаточно дорогостоящие Синие колбы через весь завод, что крайне накладно; во‑вторых, места для «обратного» хода конвейера внезапно не нашлось и пришлось вести их по достаточно запутанному пути, чтобы обойти все уже существующие дорожки Шины. В итоге нашлось неожиданное решение перенести Лаборатории в центр Шины, что решило эти две вышеуказанных проблемы, но добавило кучу работы по переделке Шины
Такие же проблемы были и с патронами, и ракетным топливом для поездов, и с ядерным топливом для электростанций. В общем, Шина начинает усложняться и явно не этого хотели от SOA архитекторы в своё время.

В целом по карте загрязнений можно увидеть, что активно работает только заводы в начале и конце Шины:

Объясняется это просто: в начале производства находится электростанция и переплавка руд, поэтому они «фонят» всегда и сильно. В конце находятся недавно запущенные заводы, которые ещё не успели заполнить Шину своей продукцией. Ну а в центре (преимущественно) находятся уже те заводы, которые успели отработать и остановится из‑за того, что «Выход заполнен».
Есть и хорошие новости:
Во‑первых, если организовывается производство чего бы то ни было, то можно быть уверенным, что уже через полчаса у нас будет много выходного продукта от него;
Во‑вторых, сделать дублирующее производство, если чего‑то не хватает, проще простого — скопировал и подключил к Шине. Например, я так делал с шестерёнками и зелеными/красными микросхемами и получил заметный прирост их производства. Главное — это вовремя сообразить, что у тебя есть нехватка чего‑бы то ни было.
Касательно расширения самой Шины: ближе ко второй половине игры строить её стало морально легче — то ли из‑за обилия комплектующих для неё, то ли получилось просто привыкнуть к этой работе. Но это чисто ощущение — времени на неё тратиться примерно столько же, как и в начале.
Интересности были с электричеством:
Сначала оно кончилось просто потому‑что стало поступать мало воды — пришлось переносить его со старого места ближе к озеру (по сути подключать воду в обход Шины). Позже истощилась шахта с углём начались нарушения поставки угля к бойлерам — пришлось отвлекаться и аварийно создавать ещё пару удалённых шахт угля. Ну и аккурат к переходу на АЭС я понял, что достиг максимума в использовании паровых двигателей. Конечно, можно было бы ещё попробовать как‑то оптимизировать подачу пара, но благо этого не потребовалось.

Атомка без проблем запустилась не смотря на достаточный долгий процесс обогащения урана — Шина позволила принять много урана и достаточно быстро обеспечить подачу урановых стержней на Шину. Если помните, на Monolith'е я АЭС сделал чуть ли не в конце игры так как процесс обогащения урана еле‑еле «разгонялся».
Ну и последнее — по исследованиям:
Колб как таковых всегда хватает — делаешь производство и их всегда поступает тысячами в Шину. Но сделать производство новых видов колб реально занимает много времени. В итоге получается такая картина: быстро открываются все исследования, которые требуют тех колб, производство которых у меня уже налажена, но потом возникает долгая пауза в исследованиях так как для них нужны новые виды колб; потом производство новых видов колб всё же запускается и вся очередь исследования достаточно шустро открывается; потом опять начинается потребность в новых видах колб и начинается долгая пауза... Чую, что итоговый график будет похож на лесенку — посмотрим по завершению текущей игры. Напомню, что в Monolith'е была ситуация более сбалансированной: пока изучаешь текущее исследование — активно строишь заводы на новые виды колб (хотя и под конец игры этот принцип стал сбоить).
В общем, если вы используйте SOA, готовьтесь к тому, что вы будете долго‑долго оставлять Бизнес без актуальных фич просто потому‑что морочитесь с Архитектурой как таковой, но потом сможете выкатить всё пачкой и с достаточно большим запасом по производительности.
Рывок до конечной цели
Пришла пора начинать создание ракеты. Тут можно выделить три интересности:
Во‑первых, хоть я и расширял создание Зеленых микросхем — их всё равно катастрофически мало. А всё потому‑что их производство находится очень далеко от актуального производства и большая часть продукции «сжирается» по пути. И тут не помогает ни переход на Красные конвейера, ни переход на улучшенные виды заводов, ни масштабирование. В общем, индивидуальный контроль внутри Шины требует дополнительных трудовложений и ещё больше увеличивает сложность Продукта.

Во‑вторых, под конец я столкнулся с похожей мыслью, что была и в начале — «Зачем мне выводить в Шину дорогостоящее производство, если можно подключить её в рядом стоящую ракетную шахту». Посмотрите сами на то, как близко располагается производство Спутников от Ракетной шахты и думаю, что у вас тоже возникнет желание не тянуть их в Шину, а подключить напрямую. Но правило есть правило.

И на этот раз это реально не окупилось — ну зачем мне полная линия дорогостоящих спутников, если достаточно одного раз в несколько часов?
В третьих, из‑за перепроизводства начали заметно кончаться уже существующие шахты/жилы нефти, меди и железа. Это странно так как я их достаточно много наделал когда подключал ЖД. Но, видимо, это такая особенность Архитектуры — так сказать «Цена за самоподдержание».
Итого по финалу:
Затрачено реального времени в 23 дня;
Убито жуков: 2'411'763
Убито червей: 3848
Убито ульев: 3626



Вот ещё я сделал гифку сравнения размера завода с Monolith'ом:

Сохранение (Поместить в%USER%\AppData\Roaming\Factorio\saves)
Видео реплея: YouTube и VK Видео
Во всей этой картине меня особенно пугает ни затраченное время, ни количество убитых кусак, а на почти 2.4к (!) убитых Чудовищных червей. Не думаю, что другие архитектуры покажут такие же цифры.
В целом приложение получилось достаточно производительным и в меру удобным в плане расширения. Но уж очень громоздкое — ты идёшь на километры в одну сторону и никак ты с этой дороги не свернёшь.
Мне этом приложение напоминает старые, исполняемые файлы на Java: один большой, исполняемый файл, который просто, но долго переносить, а так же запускается он крайне медленно.
Сразу же после окончания у меня встал вопрос: «А сколько же я времени убил на развитие Шины по сравнению с остальными работами?». По ощущениям это было около 40%. Чтобы проверить это я поделил реплей на 11 частей и замерил, сколько времени я тратил на работу с Шиной. Вот результат:

В целом ощущения не подвели — 30–40% времени в зависимости от этапа. При этом можно заметить, что график достаточно равномерный и по мере развития приложения баланс количества работы над Шиной к работе над самим Приложением более‑менее сохраняется.
Теперь переходим к замеру параметров данного Архитектурного стиля.
Подведение итогов и эксплуатация
Evolvability
Тут мы сравниваем, как быстро мы провели открытия различных исследований.
В отличие от Monolith'а, в текущем Архитектурном стиле пришлось изучать ещё много чего дополнительно, чтобы справится с Жуками и построить завод на озере. Плюс был немного изменён порядок исследований.

Вот график получился такой:

Что можно сказать по этому графику:
Самое главное и очевидное с первых часов игры — на достижении всех основных целей потребовалось в 5 раз больше времени, чем в Monolith'е. То есть, чтобы примерно сравняться по времени разработки с Monolith'ом нужно увеличивать команду разработки в 5 раз.
Я знаю правило по поводу увеличения количество сотрудников в проекте вида «две женщины не могут родить в 2 раза быстрее», но тут я это намеренно опустил из расчётов так как другой коэффициент продуктивности по увеличению количества программистов я удачо применить не могу. В разных компаниях эта формула разная: можно нанять наивысших специалистов с ЗП по 1 кв.метру квартиры в Сингапуре в месяц, но которые будут работать 24/7 и выдавать ту самую удвоенную (а то и больше) скорость разработки; а можно нанять толпу лентяев за пачку Анакома и удивляться, что ничего не ускорилось. В общем, берите пока наиболее простой расчёт от меня и накладывайте его на свой реалии.
Сразу видно, что в Monolith за то же самое время мы смогли сделать значительно больше фич. Так что сразу становится понятно, что SOA — это не про скорость выхода фич. И на эту картину влияет ещё и то, что приходилось изучать дополнительные (сервисные) исследования типа «Отсыпки территории» или военных исследований — в том же Monolith на них не пришлось бы тратить время.
Как только мы в начале игры закончили Monolith‑времянку, мы почти сразу же получили не хилый буст по фичам, который и не снился в Monolith'е — на первых порах мы даже обгоняли Monolith по некоторым исследованиям. Но это впечатление оказалось обманчивым и утонули в архитектуре мы достаточно быстро. А за это время конкуренты уже снимают все «сливки» с рынка.
Та самая «лесенка», о которой я предполагал ранее, явно проявилась. Если в Monolith'е у нас скорость исследования и скорость развития приложения шёл более‑менее равномерно, то в SOA у нас при организации нового производства колб быстро‑быстро проходили исследования и дальше просто начиналась пауза — исследования ждали, когда откроется производство новых цветов колб.
Ещё можно заметить, что у нас в SOA первые исследования прошли немного раньше, чем в Monolith'е. Это связано это с тем, что в SOA я строил временный монолит как попало (лишь бы обеспечить себя ресурсами на первое время), а потом просто всё снёс. А в Monolith я изначально пытался все строить более‑менее правильно, держа в голове, что всё это будет расширяться. В общем, это ещё больше сказывается на ложности мышления в начале жизни продукта: пока мы не закопались в проблемы архитектуры кажется, что всё будет быстро и бодро. А потом Великий облом.
В общем ситуация странная: относительно производства простоев нет и всё идёт в сторону Прекрасного Продукта, но относительно Бизнеса мы прямо очень сильно контрастируют на фоне Monolith'а по срокам и бюджету.
Ну и напомню, что из всей команды разработки 30–40% будут работать полностью с Шиной — это те самые 30–40% времени на обслуживание Шины, что мы высчитали ранее. Изначально кажется, что эти 30–40% нивелируются в SOA‑архитектуру, но «увы и ах».
Agility
Тут мы оцениваем, насколько раньше/позже у нас произошли важные события в нашем Продукте.
Таблица по производству и прочим событиям:

К сожалению, у меня пропала информация по «Новой атаке жуков». Ну и ладно — ценность ещё околомизерная.
Как видно, в SOA произошло больше разнообразных событий: тут и с ульями пришлось повоевать, и электростанции переносить (и не раз), и появилось такое понятие как «Временный монолит» (просто ряд производств, чтобы хотя бы физически можно было начать строить основную архитектуру) и пр. При этом в Monolith'е тоже были свои уникальные события, но сильно меньше.
Собственно из‑за того, что у нас некоторые события не случились в том или ином стиле, график будет немного «рваным»:

Можно смело сказать, что из‑за использования нашего архитектурного стиля подавляющее большинство событий произошли сильно позже или не произошли.
А ключевые события относительно Monolith'а случились в следующем соотношением:
Начало строительства ЖД — в 8.1240 раз позже;
Запуск АЭС — в 5.2927 раз позже;
Отказ от сжигания угля — в 4.9593 раз позже;
Запуск ракеты — в 5.1566 раз позже
Ну в общем мы поняли: SOA это не про скорость разработки явно.
Perfomance
Ну что у нас по производительности нашего приложения? Может хоть тут SOA покажет преимущество по сравнению с Monolith?
Проверяем:
Производство | Monolith | SOA |
Производство ракетных модулей | 84 | 30 |
Производство спутников | 1 | 7 |
Производство колб | 5862 | 40 000 |
Повышение производительности действительно есть, а как и понижение:
Ракетные модули получили прирост в 35.71%
Спутники — 700%
Коблы — 682.36%
На самом деле тут есть объяснение того, что не все производства получили прирост по сравнению с Monolith — чем дальше производство находится по Шине, тем меньше ему ресурсов достаётся. А от этого страдает итоговое производство на конце Шины и многократно повышается производство ближе к началу шины. То есть колбы находятся ближе к середине шины и им достаётся много ресурсов, а располагающиеся сильно дальше сборка ракетных модулей уже получает сильно пониженное количество ресурсов. Исключение тут только спутники — они находятся в самом конце и им достаются все остатки ресурсов и поэтому их произвелось так много.
Вот как это работает в миниатюрной среде:

Вот изначально выглядит эксперимент: мы на вход шины даём 100 штук синих конвейеров, а по ходу шины у нас есть 5 ответвления, где стоят свои счётчики. Ну и пустив наши 100 синих конвейеров на шину они распределятся следующим образом:

В первое ответвление попадёт 13 штук конвейеров; во вторую — 10; в третью — 8; четвертую — 7; в последнюю ВНЕЗАПНО 14.
Вот с этим и приходилось часто работать с моей конфигурацией шины: чем дальше идёт шина, тем меньше ресурсов остаётся на ответвления, но при этом в конце производство наоборот самое обеспеченное на расходники и поэтому так всегда большая производительность. Таким производство спутников оказались в конце шины и поэтому они собирали все не распределённые остатки на себя — а именно синие микросхемы.
Но переживать по этому поводу не стоит так как у нас ещё будет шаг с Конфигурированием — может там получится ещё вывести производство ракетных модулей до хороших величин.
Ещё в SOA обнаружилась одна интересность: если в Monolith'е мы получали буст производства в течении нескольких минут, то в SOA на это уходит чуть меньше часа — сырьё долго идёт производственный путь с начала Шины до целевых производств.

Более того, если подождать ещё, то можно заметить, что оно ещё и медленно разгоняется и ждать стабилизации производства приходится достаточно долго — около 12-ти часов.

А в целом результат явно хороший. Хоть в чём то мы худо‑бедно выиграли Monolith на текущий момент:)
Deployability
Тут мы оцениваем, насколько долго мы будем строить второй экземпляр завода по времени — то есть сколько времени понадобится на разворачивания второго экземпляра нашего приложения.
Перенос осуществлялся путём полного копирования завода и размещения его немного ниже. И на эту операцию мой компьютер завис минут на 5:

Надежда была на то, что у нас скорость подобного строительства будет быстрее за счёт большой производительности и больших запасов. Но всё это достоинство просто разбилось от величины самого завода. По итогу получились такие цифры:
Событие | для Monolith | для SOA |
Нехватка конвейеров | 200 минут | - |
Запущено второе производство конвейеров | 248 минут (100%) | 1700 минут (685%) |
Полный запуск второго завода | 473 минут (100%) | 2467 минут (521%) |
Нехватки расходников действительно не наблюдалось — можно было легко запить весь инвентарь и весь автомобиль всем необходимым, а после идти строить. Единственное, что не всегда хватало — аккумулятора для дронов и приходилось часто стоить руками.
В общем и целом, большие объёмы дали о себе знать — на то, чтобы развернуть копию завода ушло в 5.215 раз больше времени, чем на Monolith.
Configurability
Тут мы будем пытаться пробовать перенаправлять производство на что‑то одно целевое — отдельной на произвоство колб в ущерб ракет, отдельно на производство ракеты в ущерб колб. И всё это без строительства — по сути в нашем распоряжении есть только настройки конвейеров и манипуляторов.
В SOA оказалось значительно удобней находить место для конфигурирования: достаточно просто найти производство, которое нам необходимо ускорить и далее просто глазами идёт по шине в поиске тех мест, которые нужно перенаправить. Но времени это всё равно занимает много — опять же из‑за размера шины.
По итогу получились вот такие результаты по сравнению с Monolith'ом:

Как не странно, по времени конфигурирования на производство ракет и спутников мы совпали с Monolith'ом прямо минута‑в-минуту. Я даже трижды эти цифры перепроверил — настолько не верилось, что оно будет равным с Monolith'ом. Но вот время конфигурирования по колбам уже поставило всё на место — в SOA конфигурировать дольше.
При этом «дольше» не равно «сложнее»: если в Monolith приходилось прямо прямо думать над каждым заводом в том плане, что в нём нужно переключить (и нужно ли вообще), то в SOA я больше работал спинным мозгом — просто глазами отслеживал пути и настраивал его в нужной точке по заранее выработанному способу.
При этом в Monolith эта скорость плавающая — оно просто зависит от количества производств. А в SOA для любой настройки мне ПРИХОДИТСЯ пробегаться по всей шине. От сюда и плюс‑миную одинаковое время конфигурирования приложения в SOA — оно зависит не от размера задачи, а от размера приложения.
А вот по производительности я очень доволен: мы обогнали аналогичный сценарий Monolith по всем параметрам. Так что записываем SOA в победители — в решающий момент выжать из него производительности можно намного больше, чем в Monolith.
Testability
Теперь попробуем узнать, насколько удобно наше приложение тестировать с разных точек. То есть у нас определено три сборки (Tier) ресурсов и мы будем пробовать подключать их бесконечный поток к приложению и следить за производительность. Таким образом мы сможем искать наиболее «узкие» места в производительности.
Сам процесс опять же завязывается на шину — мы просто в нужном месте в шине ставим бесконечные сундуки и подключаем их к шине

Подключив в разные места такие конструкции получились вот такие цифры производительности:

Касательно тестирования производительности по Tier результат выглядит намного лучше, чем в Monolith. Как минимум потому‑что в SOA видна явная корреляция производительности от дальности до целевого произвоства — чем дальше, тем сильнее снижается производительность. У Monolith в этом плане были аномалии: то производительность между Tier'ами застревала, то проседала реверсивно. Так что это значительный плюс — обрабатывать подобные данные значительно проще.
А вот тоже самое, но уже по времени организации тестирования:

По времени организации тестирования мы тоже выиграли. Почти что в 2 раза. А всё потому‑что в SOA у нас достаточно было найти нужно место для организации нагрузки и просто копипастом пустить потом расходников в шину и дальше приложение само разберётся, что/куда там отсылать. А вот в Monolith приходилось тоже самое делать каждый раз уникально — особенно в плане расположения бесконечных сундуков в необходимом количестве.
Так что в этой категории SOA однозначно выиграет!
Scalability
А что у нас получается по производительности в случае, если мы будем вертикально и горизонтально масштабировать наше приложение можно узнать на этой таблице:

Максимальный прирост производительности дало именно вертикальное масштабирования. Собственно в SOA на это и был расчёт, когда его изобретали — при необходимости добавляем больше экземпляров какого‑то необходимого сервиса, подключаем его к шине и получаем прирост производительности.
Хотя, с другой стороны, времени на полное вертикальное масштабирование было затрачено очень много — почти 5 часов! Как и любые сверхвысокие показатели по времени в SOA — приходится спихивать их на огромную величину приложения. Один сервис вертикально смасштабировать может будет относительно быстро, но вот масштабировать всё — это уже целая эпопея.
С горизонтальным масштабированием чуть сложнее — добиться удвоеной производительности у нас получилось только у Ракетных модулей. Более того, получилось организовать производство Ракетных модулей более чем в 2 раза и, как я понимаю, это сказалось том, что мы не достикли X2 у спутников и колб.
На самом деле если подождать достаточно долго (часов 15), то приложение стабилизируется и мы получаем 330 ракетных модулей (1100%), 17 спутников в час (242%). Но при этом количество колб падает до 19 600 (49%) — в основном из‑за просадки производства стали. Но мы эти цифры не возьмём в общую статистику. Просто чтобы не делать исключений.
Elacticity
Тут мы смотрим на прирост производительности при Горизонтальном масштабировании при затраченном не его реализацию время. Таким образом получаем KPI — чем быстрее мы сможем смасштабироваться и, при этом, чем больше получим эффект по производительности.
По прошлым экспериментам мы получили результат, что 2467 минут мы получили прирост Ракетных модулей на 156%, спутников на 42% и коль на 31%.
Высчитываем KPI:
Ракетные модули: (2.56–1)/2467=0,00064
Спутники: (1.42–1)/2467=0,00017
Колбы: (1.31–1)/2467=0,00013
Ну и с этого момента будем заносить эти данные в таблицу:
KPI | Monolith | SOA |
Ракетные модули | 0.00093 | 0,00064 |
Спутники | 0.00423 | 0,00017 |
Колбы | 0.00097 | 0,00013 |
В общем, относительно Бизнеса есть кардинальный проигрыш по всем параметрам так как весь прирост производительности в SOA просто нивелируется кратно большей долготой реализации развёртывания. При чём проигрыш в некоторых местах многократный. Иными словами, относительно Бизнеса SOA выглядит максимально неоправданным по сравнению с Monolith.
Cost
Тут мы определяем, какую площадь завода и потребление его электроэнергии — это прямое отражение стоимости одного запущенного приложения.
Собственно, большие проблемы с Жуками связаны исключительно с занимаемой площадью приложения. Сравните его с Monolith'ом:
Параметр | для Monolith | для SOA |
Площадь общая (любые постройки) | 634 489 m2 (100%) | 3 786 258 m2 (596%) |
Площадь полезная (производственные здания) | 72 545 m2 (100%) | 1 944 721 m2 (2680%) |
Энергопотребление | 125 МВт (100%) | 283 МВт (226%) |

Общая площадь поражает — более чем в 26 раз в отличие от Monolith. При этом именно полезная часть занимает примерно в 6 раз, чем в Monolith.
Грубо говоря, если мы захотим развернуть наше приложение на каких‑то серверах, то сервера явно потребуются мощные. Более того, мой компьютер уже еле тянул такой большой завод.
Fault Tolerance
Тут мы пробуем сломать наш завод путём DDoS‑ и хакерской атак.
С жуками просто: они прорвали оборону через 125 минут. При этом под раздачу попал не сам завод, а точки добычи ресурсов и пути к ним. А без добычи ресурсов сырьё просто кончилось и всё встало.
С вторым вариантом (имитация DDoS) вышло интересней — на то, чтобы полностью застопорить работу завода путём посылания «паразитных» поездов (трафика), ушло 7:40:19 (почти 8 часов) времени.
По количеству поездов ситуация следующая:
Событие | для Monolith | для SOA |
Базовое количество поездов | 19 (100%) | 40 (100%) |
Проблема стала видимой | 33 (173%) | 109 (272%) |
Началось снижение производительности производства | 68 (357%) | 219 (547%) |
Полная остановка производства | 110 (578%) | 221 (552%) |
Поскольку в данном Архитектурном стиле ЖД играет более значимую роль из‑за своих объёмов, то и она оказалась более стойкой к большому количеству поездов. По сути, если не считать мелкие улучшения и проблему с кольцевой дорогой — производство упало только под конец, когда станции просто не могли обменяться друг с другом поездами из‑за занятости обоих. Хотя в процентном соотношении разницы не очень много, конечно, но мы тут больше смотрим на количество поездов.
Deadlock на кольцевой дороге:

По финалу ЖД застопорилось примерно вот в таком виде — поезда просто упёрлись в установленный лимит составов на станциях и не могли двигаться так как им просто некуда ехать:

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

Domain Pertitioning
Тут мы смотрим, насколько легко логически разделить завод на зоны производства и на сколько они плотно друг к другу располагаются — это напрямую влияет на сложность расширения продукта в будущем.

Основные зоны производства стоят параллельно Шине и мне удалось не допустить ни одной зависимости.
Что бесспорно, это у нас стало лучше, чем было в Monolith'е — там у нас нашлось аж 12 таких проблемных зон:

Так что фиксируем «0», радуемся и идём дальше.
Abstraction Level
Тут мы высокоуровнево обозначаем части продукта по назначению и смотрим, как сильно оно перемешано:

По количеству «анклавов» в зонах как будто стало сильно больше — если в Monolith таких «анклавов» было 3 штуки максимум, то в SOA я насчитал зону «ресурсы» в 7 таких анклавов. Вот сравните с тем, что у нас было в Monolith:

Но в целом ситуация с «рваными» доменами у нас аналогичная — «рваные» только зона Ресурсы, Основной завод и Переработка ресурсов. Итого зоны 3 штуки. Как и Monolith. Фиксируем этот результат.
Общий вывод по SOA
Итак, представляю вам призёров по номинациям на текущий момент:

Если сравнивать с Monolith'ом, то можно выделить следующие достоинства SOA:
Значительно больший запас производительности — продукт реально сможет как принять больше нагрузки изначально, так и иметь значительно больший прирост производительности при масштабировании. Хотя преимущество не однозначное так как мне не удалось достигнуть производство Ракетных модулей больше, чем у Monolith. Хотя перспектива явно есть.
Конфигурирование приложения получается намного выгодней. Хотя по времени конфигурирования SOA немного проигрывает Monolith'у.
Тестирование архитеруты SOA является абсолютным выигрышем как по скорости организации тестирования, так и по обработки данных тестирования. Иными словами, тестировать отдельные части SOA намного удобней, а результат более очевиден, чем в Monolith.
Вертикальное масштабирование очень выгодное в Приложении — добавляем больше ресурсов в сервисы и сразу получаем прирост производительности. При этом можно там масштабировать как и отдельные, наиболее загруженные сервисы, так и все сервисы разом. И в последнем случае получим аж трёхкратное увеличение производительности. Это может быть очень полезным.
Приложение более устойчиво к проблемам. Как к DDoS за счёт запаса производительности, так и к падению отдельных частей завода. Хотя в последнем разница и не очень существенная.
Связность между сервисами действительно получилась идеальной — нет ни одного сервиса, который не был бы напрямую привязан к Шине. А значит сервисы можно легко обновлять/заменять без боязни что‑то поломать косвенно (главное соблюдать интеграцию с Шиной и только с ней). В том же Monolith с этим было больше проблем.
Но недостатков у неё имеются:
Размеры и организация приложения сильно растягивают разработку его: как по времени внедрения новых фич, так и по общей готовности приложения к запуску в Прод. В 5 раз дольше между прочем.
Объем приложения получится очень большим. А следовательно и большие накладные расходы. И при этом большую часть приложения занимает Шина — 30–40% всего приложения. В общем, для запуска такого приложения маломощные сервера не подойдут — нужно будет закупать прямо мощный и дорогой сервер.
Горизонтально раздеплоить такое приложение может быть целой проблемой. В основном из‑за объёмности самого приложения. По итогу по времени это никак не окупает даже прирост производительности и Бизнес со своим KPI явно будет не доволен.
Как говориться, «Долго, дорого, качественно». Получается, что все недостатки SOA связаны именно с Бизнесом и его неудовлетворённым желанием выпустить продукт быстро и дёшево — именно поэтому SOA имеет столь негативную славу. Если Бизнес захочет новую фичу — он будет привлекать как минимум двух программистов (Шины и Сервисов) и ещё достаточно долго ждать, когда они договорятся и сработаются между собой.
Да, у нас получается достаточно структурированное и производительное приложение и любой программист бы им гордился, но если со стороны Бизнеса эти расходы не окупятся — приложение уйдёт быстро уйдёт в раздел «Провальные». А дополнительные накладные расходы и проблемы при горизонтальном масштабировании этому явно не помогут.
Так что применять SOA стоит только при отсутствии конкуренции, спешки и необходимостью большого запаса производительности. Если вы планируете сделать приложение без особой спешки и со стабильностью «на года» — SOA вполне может быть вашим вариантом. Но если есть конкуренция и жесткие сроки — в SOA лучше не лезть и пилить другую архитектуру.
В следующей передаче — Service‑Based Architecture или SeBA
В следующей статье мы продолжим идти по хронологическому порядку развития Архитектурных стилей и перейдём на Основанную на сервисах архитектуру (Service‑Based Architecture или SeBA). Исторически команды, познав горький опыт использования SOA начали думать, что делать дальше и решили (наконец‑то) заменить громоздкую шину на REST API.

Что из этого у них получилось — узнаем в следующей статье! А пока я временно прощаюсь с вами, душевно благодарю за прочтение моей работы и ухожу опять на полгода запускать новую игру с нуля — пожелайте удачи, ибо я вам этого тоже желаю;)
