Много шуму поднято из-за публичного обсуждения "вхождения во власть" Илона Маска с его новоприобретённым Твиттером. Это действительно хороший повод для понимания того, что творится в современных информационных технологиях. Поэтому рассмотрим проблему со стороны оппонентов повсеместно распространённой излишней сложности, коллективно называемой "микросервисная архитектура". Итак, на Хабре появилась статья защитников микросервисов. Очень кстати, теперь есть о чём говорить предметно. Общий посыл статьи такой - у каждого микросервиса есть крайне важная ниша и потому - всё сделано правильно. Но я думаю, что многим очевиден несколько натянутый характер заявления, не подкреплённого конкретикой. Конкретика - это цифры. Давайте попробуем оценить приведённые защитниками микросервисов аргументы именно в цифрах. Традиционно микросервисы обосновываются в контексте бизнес-процессов, в которых эти сервисы выполняю какую-то важную роль. И потому логично, что автор "аргументов за" привёл список процессов. Пройдёмся по нему. Место микросервисов в процессе не указано, но попробуем "догадаться с трёх раз", используя опыт работы в аналогичных компаниях. Основной способ достижения целей ИБ (информационная безопасность) простой - ограничения. Это и пароли, и политика требований к местам пользователей, и всевозможные прокладки между серверами и остальным миром, и много чего другого. Но суть здесь простая - это администрирование. У админов тоже должна быть какая-то консоль, но для неё обычно не нужно писать микросервис, ибо есть привычная админам командная строка привычного им Unix-подобного софта. А там, где нужно работать с данными, вроде задачи администрирования пользователей, все соответствующие инструменты давно написаны и админы про них отлично знают. В целом получается, что для основных задач инструменты есть, а микросервисы здесь не особо нужны. Но есть ещё задача мониторинга. Мониторинг плох тем, что должен быть плотно привязан к существующему набору сервисов, поэтому здесь можно допустить наличие специфического софта, который выполняет хоть и простые, но зависящие от наблюдаемых микросервисов функции. Таких функций немного. Обычно большая часть мониторинга заключается в получении информации - жив сервис, или упал. Это достигается простейшим запросом по указанному в настройках адресу и через указанный там же протокол. Такая задача решена давно и не требует никаких микросервисов, кроме одно сервиса (не микро, а вполне приличного по функционалу). Этот сервис опрашивает по кругу все сервисы, по которым есть данные в его списке. Задача опрашиваемых сервисов - вернуть хоть что-нибудь без ошибки. Это чаще всего достигается без разработки чего-то нового в самом сервисе, потому что мониторинг вызывает готовые для других задач обработчики с безопасным для такой ситуации набором входных данных. Отсюда вывод - один сервис закрывает большинство задач по мониторингу. Добавим к нему ещё один, который решает узко-специальные задачи, требующие проверки не просто "жив или мёртв", но чего-то более сложного, учитывающего бизнес-логику приложения. Таких задач обычно мало и с ними справится сервис, написанный начинающими студентами с курсов по вашему любимому языку программирования. Итого - нам нужно два сервиса. Есть ещё задача анализа трафика. Это задача "междисциплинарная", то есть она нужна и в ИБ и в других местах. Поэтому добавим ещё 0.1 сервис, приходящийся на долю ИБ. Правда анализ может быть очень тяжёлый, потому что каждый день анализируется много гигабайт данных, значит здесь нам потребуются мощные сервера и распределение задачи на параллельную обработку по доступным серверам. Но сервис всё же один, хотя и можно выделять - эта долька для ежа, эта долька для ужа, и т.д. И это тоже информационная безопасность, правда с немного другой начинкой - она фильтрует. То есть здесь нужны алгоритмы, умеющие отличать бота от человека. Да, это отдельная задача. И она привязана к логике приложения, потому что именно логика приложения нужна человеку, а боту нужно лишь рекламу повесить - в этом отличие. Только зачем же здесь городить тысячу сервисов? Здесь две составляющие - простая, которая решается стандартными средствами вроде анализа адресов и интервалов между запросами, и сложная, которая работает вместе с приложением и фильтрует, основываясь на его логике. Первая давно реализована и требует одну прокладку между пользователями и приложением. Вторая, как часть приложения, работает вместе с ним и могла бы вообще не создавать ни одного дополнительного сервиса. Но что бы вынести сложность в отдельный компонент согласимся на парочку дополнительных служб. Но не на тысячу. Нам нужно управлять нашими серверами. А с ними ещё и сетями. И туда же - группами администраторов. А потом ещё создать группу управления группами. А к ней совет директоров. А к нему аудиторскую палату... Но мы этого делать не будем, мы попробуем просто обрисовать задачи, а накручивание около них бюрократии оставим Илону Маску. Итак, сервера. Их нужно учитывать. Учёту подлежит и всё остальное - сети, админы, их любимый софт, и все-все-все юзеры. Да, это отдельная задача. Но повторю старую истину - всё украдено до нас. Это означает, что все эти админы и юзеры давно записаны в какой-нибудь LDAP (учётную систему с приоритетом на права доступа и описание ресурсов). Это, разумеется, сервис. Но сколько нужно админов на пусть даже 100 000 серверов? По большому счёту это вопрос о частоте изменений, а не о количестве серверов, потому что сегодня изменения устанавливаются автоматически, и не важно, хоть на один сервер, хоть на 100 000. Хотя я верю, что команды Твиттера сумели собрать страшный зоопарк из серверов, а потому и автоматическая установка намордников на сотню видов животных потребует с десяток различных протоколов и прочих приседаний. Пусть в итоге на весь зоопарк будет пятнадцать сервисов - для жирафов, для рыбок из аквариума, и т.д. Пока, всё равно, сильно меньше тысячи. Здесь мы должны немного погрузиться в разработку софта. При нормальной его организации имеем несколько серверов для одной команды разработчиков. Но важно отметить, что сервера эти ничего общего с требованиями к промышленным серверам не имеют. То есть они могут упасть, они могут сломаться, на них забудут установить обновление, и даже пусть рухнет весь дом, где стоят эти сервера - пользователи Твиттера этого не заметят. Потому что им нет никакого дела до того, что творится на ноутбуке у разработчика. И у тестировщика. И у менеджера проектов. И даже у директора по качеству. И даже у самого, не побоюсь этого слова, Илона, который в Маске. Хотя есть задача мониторинга на сбои, что бы разработчики, если сбой по их вине, эти проблемы устранили. Но выше мы уже говорили - есть сервис, который опрашивает систему про сбои, и есть аналитика, они-то всё разработчикам и доложат. Хотя можно добавить систему ведения журнала для разработчиков, то есть это расшифровка деталей, рассказывающих программистов в какой ситуации упал их любимый сервис. Количественно оценивать такую систему можно по разному, в зависимости от качества самих разработчиков и безжалостности их по отношению к товарищу Маску. Одним разработчикам хватает относительно краткого описания ошибки, а другим нужно на каждый запрос пользователя получить мегабайт дополнительной информации - отсюда разница в нагрузке. Но понятно, что при нормальной разработке запись в подобный журнал не должна нагружать систему больше, чем целевая функция. И желательно, что бы нагрузка от журнала была этак раз в сто поменьше. Поэтому выделим на журнал долю в 0.01 от общего количества серверов, обслуживающих компанию. При 100 000 серверах (что явно много) получим 1000 серверов под журнал. Но, особенно если разработчики грамотные и умеют уложить все записи в один сервис, логически вся эта 1000 серверов будет представлена одной службой. Но ладно, допустим, что в в Твиттере одни неумёхи и им нужно 20 разных служб под одну универсальную задачу журналирования. Но опять имеем много меньше 1000 сервисов. Добавим сюда работу с отзывами пользователей и разного рода опросы, которые суть бизнес-логика. И сразу заметим, что пользователи в основном пользуются платформой, а не отвечают на вопросы из очередного опроса от департамента по работе с клиентами. Отсюда мораль - эта нагрузка опять никакая. Пусть это будет пять сервисов. Хотя при желании можно уложить их всех в один - сервис взаимодействия с клиентом. Но никак не в тысячу сервисов. Это опять продолжение разработки. А потому здесь многое опять зависит от вольностей наших славных программистов. Но суть происходящего простая - команды складывают новый код в некое хранилище, которое они называют "репозиторий", это событие обнаруживается следящим за репозиторием сервисом, после чего он пытается сделать так, что бы появившийся код заработал на серверах, обслуживающих пользователей. Детали внутри такой попытки могут быть разнообразные, но для нас важно одно - мы опять имеем дело с одним сервисом, а не с тысячей. Хотя опять же, если Твиттер собрал у себя тысячу команд, и каждая сочинила для себя своё собственное решение по передаче "в бой" своего кода, тогда, разумеется, Илону Маску нужно срочно доложить о том, что у него действительно есть тысяча сервисов. Но вот в нужности такого количества велосипедов на стороне разработчиков у меня есть огромные сомнения. Помимо падений сервисы бывают ещё и неудобными, а иногда делают не то, что от них ожидает пользователь. Для анализа и устранения таких ситуаций существует служба поддержки. Это довольно много людей. И они обслуживают многие тысячи заявок в день, если мы говорим о масштабах Твиттера. Но здесь стоит пояснить, что все эти заявки укладываются в единую базу данных, потому что если разбивать их на много баз, то потом возникает обратная задача - для работы с заявкой нужно снова свести информацию в одно место, что даёт нам размножение работы как на входе, так и на выходе - очевидно неэффективное решение. Поэтому смело предположим, что всё-таки Твиттер как-то справился со своими разработчиками или сторонними производителями системы по работе с заявками пользователей и всё же имеет один сервис для этой цели, а не тысячу. Ну ладно, пусть десять специализированных, но уже не очень понятно зачем. И мы видим - до тысячи опять далеко. Да, это важный процесс. Это те деньги, которые зарабатывает Твиттер. То есть именно ради этого процесса всё начиналось и продолжает цвести и пахнуть. Поэтому под такую задачу смело выделяют большие бюджеты и готовы оплачивать много команд разработки, которые дотачивают все эти нейросети и прочий дата-сайенс до нужной кондиции. Но глобально задач здесь опять немного. Сервис под нейросети, сервис под статистический анализ, сервис под дискретную математику на графах и тому подобное. Плюс к этому привычная аналитика и всяческие отчёты. То есть десяток сервисов вполне может набраться. И где здесь тысяча? Опять речь идёт о работе разработчиков. Они должны выставлять наружу практически тот функционал, который используют сами. Но поскольку внутренняя среда отличается от внешней, например наличием большого количества угроз, на подобное расширение нужно вешать фильтрацию. То есть отдельную логику, специализированную именно под данную задачу. Архитектурно это может быть очередная прокладка между потребителями (в виде удалённых автоматически действующих устройств) и производителями (в виде внутренних частей приложения). На сколько частей делить прокладку - вопрос к разработчикам. Но мы видели выше, что делить можно и на одну часть, и на тысячу. Последнее, как и раньше, есть явное расточительство. Но мы ещё поговорим о нём позже. И снова мы возвращаемся к разработчикам. Давайте вспомним старые добрые форумы. Там тоже есть модераторы. И они используют тот же самый форум. Но у них на странице появляется кнопка - забанить. Вот и всё отличие от страниц обычных пользователей. На форумах о таком функционале даже не задумываются - делают частью приложения и не требуют никаких сервисов. А вот последующий разбор жалоб пользователей действительно нужно выделять в отдельную (организационную) службу. Но про неё мы уже говорили выше - это служба поддержки. Так что здесь сервисов просто нет. Задача интересная, но стоит уточнить её цель. Сильно подозреваю, что это способ привлечения разработчиков "интересными задачами", то есть они, в рабочее время, занимаются интересными делами, ну а потом Твиттер это дело оплачивает. Это, конечно, хорошо. Разработчики должны быть довольны. Как и доктора, полицейские, металлурги, и даже дворники из Таджикистана. А что, разве дворники не люди? Но почему-то дворникам не дают столько возможностей для самореализации. Ну ладно, речь ведь о количестве сервисов. Итак, что такое "OpenSource проект"? Очень просто - копируем на известный сайт свой код и пишем к нему вступительное слова, экранов на пять-шесть, если не сильно лень. И всё. Дальше - обычный процесс разработки. И всё это на стороннем сервисе. Но где же 1000 внутренних сервисов? Ну пусть будет сервис отчётов перед начальством за непонятно на что потраченное рабочее время. Один. Не тысяча. Ну да, как только подсистема осознаёт свою значимость, тут же появляются адепты "совершенствования методологий" и "правил оформления". Ну куда же нам без ГОСТ-ов на код? Но я бы не стал под это дело заводить серьёзный сервис. Хотят ребята побаловаться - вот вам куча внутренних серверов для разработчиков, на них и поднимайте свой мега-сервис. Опять один. Соглашусь, это важная задача. Хотя, если честно, никто в Твиттере (как и в других системах) документацию не читает. Ну почти никто. А вот документировать внешнее API нужно, и обязательно качественно. Но ведь мы уже выше рассмотрели эту задачу. Значит лишь для тех долей процента от пользователей, которые сумели найти ссылку "Помощь" и разобрались там в сложной навигации по содержимому, нам и нужно писать документацию. И это не "высоко нагруженная" система. Это доли процентов от миллионов в день общего количества пользователей. То есть это тысячи, ну пусть десятки тысяч запросов. Такую нагрузку держит самый дешёвый виртуальный сервер за 3 бакса в месяц. Можно ли его приравнять к тысяче микросервисов? Вопрос риторический. И всё же остаётся задача - организовать работу технических писателей и их взаимодействие с разработчиками. Но это же опять внутренняя кухня разработки. А у них свои независимые и ненагруженные сервера. И пусть их там хоть 1000 штук, и даже пусть разработчики поиграются и поставят на каждый по сервису для документирования, но для пользователей Твиттера-то это что меняет? Зачем здесь все эти провода? По прежнему вопрошает Илон наш, свет-Маск. Да, раньше был лишь ответ на аргументы сторонников микросервисов, изложенные явно. А теперь скажем о том, о чём они сказать забыли. Зачем нужны микросервисы? Коротко - они повышают гибкость. Да, они нужны. Но всегда есть вопрос о границах. Если где-то летает муха, то мы же не будем говорить, что видим слона? Поэтому далее мы поймём, почему нужны микросервисы и где же нам поставить пограничные столбы. Как достигается гибкость? Просто - внесли изменение в часть приложения, теперь его нужно как-то отправить в бой. Но для этого чаще всего нужно что-то перезапустить. Если приложение монолитное, то перезапустить придётся всё приложение целиком. Это означает, что миллионы пользователей Твиттера начнут страдать. Да, они видят ответ на их запрос примерно такого содержания - этот сервер недоступен, позвоните Илону Маску, вот телефон. Илон Маск не справится с таким количеством звонков. Поэтому разработчики предложили "рубить хвост по частям". Они перезапускают один мкросервис, при этом его работу никто не выполняет, но все остальные части приложения, так же созданные как сервисы, знают, что если что-то недоступно, то есть алгоритм обработки такой ситуации. Например - можно немного подождать. Или можно отправить запрос на другой сервис. Или и то и другое, и можно без хлеба. В целом же получаем некоторую новую устойчивость всей системы в целом. Но, как вы могли заметить, при таком подходе возникает ряд дополнительных требований. Первое - все должны стать ёжиками сервисами. Второе - все должны знать, что делать, если соседний ёжик не хочет работать. Третье - кто-то должен понимать, как это огромное стадо ежей пинать столь нежно, что бы они в итоге полетели, но не убились об ближайшее дерево. Одним словом это всё называется так - сложность. Да, сложность сильно возрастает. И с ней не всегда справляются даже очень умно выглядящие разработчики. Ранее уже говорилось, что в Твиттере (и не только) всё сильно зависит от разработчиков. Значит нам нужно рассмотреть как поведут себя условно "плохие" разработчики и условно "хорошие". Для этого поймём общую картину боя. Сначала количественная сложность. Когда есть сотня микросервисов, то взаимодействие между ними требует налаживания десяти тысяч связей (пропорционально квадрату от количества сервисов). Если взять и разбить приложение на сервисы, не вспоминая о количественной сложности, то очень вероятно, что именно так и выйдет - сложность увеличится пропорционально квадрату. Поэтому нужно хорошо подумать. И здесь становится незаменим персонаж под псевдонимом "архитектор". Если он сумеет разбить систему так, что бы количество связей не возрастало до безобразия, то в таком случае мы можем переходить на систему из взаимодействующих сервисов. Ну а если не сможет - товарищу Маску придётся что-то делать с его не самым эффективным наследием. Но есть ещё и качественная сложность. Подняв тысячу микросервисов, мы сразу получим задачу на мониторинг этого зоопарка. А к ней и задачу установки отличающихся обновлений на каждый из тысячи сервисов. Вместе с задачей установки идёт задача преобразования кода в то, что сможет запуститься, что называют "сборкой приложения". А к ней прилагается команда, то есть те люди, которые ответственны за данный сервис. И эти команды склонны к размножению. Они находят для себя огромное количество задач, хотя бы даже из уже приведённого списка - им же нужно сделать мониторинг? Нужно. Им же нужно написать документацию? Нужно. И так по всем процессам, задействованным в разработке. И что интереснее, преимущество микросервисов в гибкости позволяет разработчикам писать на том языке, к которому они привыкли, что означает сильно разные подходы к разработке. Но тут всплывает ещё и задача запрячь вола и трепетную лань в одну крестьянскую телегу. А к ней - нанять на рынке всё это бесконечное количество разработчиков, тестировщиков, технических писателей, аналитиков, менеджеров проектов, админов, дизайнеров и к ним ещё отдел из секретарш, ежедневно разносящих смузи по столам для каждого участника команды (мы ведь ценим разработчиков!). И все эти люди должны быть наняты на работу с отличающимися инструментами, то есть они должны иметь опыт работы с точно такими же. Что же теперь делать отделу кадров? Правильно - раздувать штат. Вот таким примерно образом, из хорошей в своей основе идеи повышения гибкости, Илон Маск получил на свою миллиардерскую шею налог в виде никуда не исчезающей сложности. Ну что-ж, я думаю страдать о судьбе Маска не стоит, он справится. А вот о грамотном построении архитектуры информационной системы мы вполне можем задуматься. У нас перед глазами вопиющий пример из тысяч сервисов, которые требуют десяток тысяч работников, а всё для чего? Что бы пользователь мог на странице Твиттера сделать всего лишь часть от того, что любой старый добрый форум выполнял в гораздо большем объёме, не требуя такого гигантского раздувания штатов и инфраструктуры. Ещё один аргумент за микросервисы - у нас нагрузка! Миллионы пользователей! Пуленепробиваемая надёжность! И ещё time-to-market и все-все-все. Добавим деталей. Нагрузка обрабатывается за счёт распараллеливания. Можно поднять 1000 дешёвых виртуальных серверов и каждый обслужит минимум 1000 пользователей в день. Вот вам и миллион пользователей. Но для этого нужно уметь сводить запросы на одном сервере с данными от другого. Это архитектурная задача. И, как мы видим, сотрудники Твиттера её решили просто - покупаем 100 000 серверов (не виртуальных), нанимаем 10 000 человек, и вуаля - у нас даже что-то работает. Но тут уместна поговорка - с деньгами бы и дурак смог, а ты вот без денег попробуй. Вторая часть - отказоустойчивость. Это продолжение всё той же гибкости. В идеале, миллион независимых микро-сервисов легко переключится на другой адрес при падении одного из миллиона участников. Но это лишь в идеале. Хотя суть здесь простая - дублирование. И опять мы получаем задачу для архитектора. Сумеет он достичь приемлемого дублирования на 1000 виртуальных серверов - молодец. Но чаще всего получается как в Твиттере - 100 000 серверов и миллиарды в год на содержание бегемота. Третья часть - скорость разработки. Здесь люди идут по проторенной дорожке, что означает - действие по шаблону. Они смотрят, а что там у соседа. Если у соседа что-то работает и по меркам индустрии затраты приемлемые, то вывод здесь простой - я хочу так же. Но дело в том, что сосед далеко не семи пядей во лбу и, как много проблем в его внутренней кухне, смотрящий снаружи просто не видит. Поэтому копируются не самые эффективные решения, а просто "понравившиеся", то есть внешне выглядящие как успешные. Но стоит заглянуть внутрь, как все мы видим - Твиттер был несколько переоценен. Решение здесь опять лежит в плоскости внимательного и грамотного анализа требований с последующей продуманной реализацией. Опять во всём виноват архитектор. Но мы его обвинять не будем, потому что на работу в Твиттеры нанимают не по непонятным качествам типа внимательный, грамотный, продуманный и т.д., а по субъективному критерию "от 5 лет на аналогичной должности в компании Top-500 рейтинга NASDAQ". И теперь бывший разработчик из Твиттера, который не смог объяснить Маску, зачем нужны тысячи сервисов, легко устроится на аналогичную должность в другую такую же компанию, ведь у него за плечами есть эти самые 5 лет на аналогичной должности. Но хорошо ли это для разработки информационных систем? Микросервисы не плохие и не хорошие. Они - инструмент. Если не умеешь - не трогай. Но ситуация на рынке такова, что умеющих отбирать сложно, а потому мы и дальше будем наблюдать перегиб в сторону расползания неэффективности во все стороны. Но если кто-то всё же заинтересовался возможностью уменьшения затрат на корпоративного монстра, то мой ему совет - не надо вам "5 лет на аналогичной должности", вам надо грамотного и способного. Да, это означает, что лично вам придётся сидеть и самому с ним изучать матчасть. Не всю, понятно, но вникать надо. Любишь экономию? Люби и архитекторов на саночках возить.  Программист