[Перевод] Технология Serverless: снова привет, 1970-е
Я проработал с «Облаком» уже достаточно долго для того, чтобы убедиться, что ему предстоит пройти ещё долгий путь, прежде чем оно станет лучше старой доброй аренды пары серверов и запуска своего ПО на них. Сейчас в моде Serverless-решения, из-за которых у меня ощущение, что мы снова вернулись в 1970 год.
Когда-то давным-давно я притворялся, что учусь менеджменту, а на самом деле изучал кодинг на C. Наш университет находился в двух мирах: в нём существовала лаборатория с «персональными компьютерами», но в то же время имелись терминалы мини-компьютера, и в зависимости от предпочтений профессоров задания нужно было выполнять в одном из этих миров. Но обе эти системы были, по крайней мере, интерактивными и обеспечивали мгновенную обратную связь. Моему другу повезло не так сильно: на одном из курсов по технологии строительства ему дали задание, которое нужно было выполнить на Pascal и сдать в виде распечатки с университетского мейнфрейма.
Он позвал на помощь меня, потому что до этого вообще не писал код. Я пришёл к нему в гости с дискетой с Turbo Pascal, думая, что мы быстро справимся с заданием. Так и случилось, хотя я никогда не кодил на Pascal до этого: IDE даже в те времена была чудесной, и благодаря большой скорости, с которыми мы делали пробы и ошибки, нам удалось добиться нужных результатов (это были простые инженерные вычисления, которые гораздо быстрее можно выполнить на самом примитивнейшем калькуляторе, но таково было задание. По крайней мере, мы легко могли проверить правильность работы программы).
Потом мы сели в машину и приехали в компьютерный центр университета — бетонный бункер в стиле брутализма 70-х. Мы сели за терминал, ввели код, дополнили его необходимым IBM Job Control Language, который преподаватель любезно указал в задании, и нажали на «Enter» (не «Return», «возврат каретки», а действительно «Enter» — «ввод задачи»). Через пару минут запустился принтер и выплюнул пару страниц. Среди тарабарщины в верхнем регистре там было ещё кое-что: ошибка компилятора. Мы вернулись на первую клетку поля — очевидно, что Turbo Pascal и IBM Mainframe Pascal имели какие-то различия. Спустя пару часов, испортив кучу бумаги мы получили то, что нужно было моему другу: результаты правильного прогона программы. Числа соответствовали нашим записям, и мы могли пойти в ближайший бар, чтобы выпить заслуженного пива.
После этого случая я всегда подчёркиваю ценность обратной связи и особенно быстрой обратной связи. Даже в этом минимальном примере мы потратили больше времени на подстраивание кода под нужный диалект языка, чем на его написание. Медленные циклы обратной связи убивают производительность; если вы мне не верите, найдите онлайн-версию Beer Distribution Game и сыграйте в неё. Вы будете удивлены.
Вершиной интерактивности был, да и по-прежнему остаётся, Smalltalk. Я работал с этим языком пару лет и возможность компилировать и запускать тесты за доли секунды вызывает привыкание. Невероятно, насколько повышается твоя производительность в полностью интерактивной системе программирования, но для того, чтобы полностью ощутить это, необходимо попробовать самому. Это странная система, странный язык, непопулярное решение; поэтому Smalltalk по-прежнему остаётся в совершенно незаслуженном забвении.
После работы с Smalltalk я встречался со многими крупными системами на Java. Поначалу они были ужасной бредятиной, но когда возникла идея «внедрения зависимостей», ситуация начала улучшаться. Однако снова вернулся Job Control Language, на этот раз замаскированный под XML и имеющий более приятные названия, например, «Spring». Внутри код был достаточно чистым и модульным, однако чтобы объяснить компьютеру, как его выполнять, приходилось тратить примерно столько же времени на ввод, только не на языке программирования, а на языке структурированной разметки. У этого языка отсутствовали все возможности, которые необходимы для написания хорошего кода, поэтому принципы наподобие «Don«t Repeat Yourself» были забыты, и расцвело программирование методом копипастинга. Нужна новая бизнес-логика? Новый контроллер, 20 строк бойлерплейта Java, 10 строк бизнес-логики Java, 50 строк XML, чтобы прикрутить всё это к остальной системе.
По крайней мере, сейчас мы понимаем, что XML оказался благословением: редактор сообщал тебе, имеет ли твоё описание того, как соединяется код с системой, правильную структуру, а позже даже подсказывал, использовал ли ты имена, существующие в твоей кодовой базе Java.
На компилирование этих систем требовались века, на юнит-тесты — часы, поэтому очевидно, что интерактивность была ниже плинтуса. Поэтому разделение всего этого было неплохой идеей. Она не являлась необходимой, в основном она появилась из-за недостатков популярных языков программирования, однако «нужда всему научит» — хотя среднестатистическое бизнес-приложение на Java было гораздо проще, чем Smalltalk IDE, прежде чем ты добавишь единственную строку кода для создания этого приложения, оно уже оказывается слишком сложным для поддержки, поэтому выход нашёлся в принципе «разделяй и властвуй». Так родилась Service Oriented Architecture, а позже — микросервисы. Разделяй свою кодовую базу, разделяй команды разработчиков, создай множество возможностей для посредственных кодеров вырасти в посредственных менеджеров по разработке, и все будут довольны. В том числе и поставщик «железа», потому что внезапно тебе уже требуется гораздо больше оборудования на выполнение тех же нагрузок. Потому что сети медленны, и хотя можно поспорить, является ли трёхуровневая система на самом деле распределённой вычислительной системой, система микросервисов определённо относится к таковым.
На этот раз Job Control Language вернулся, замаскировавшись под данные конфигурации для работы микросервиса. Микросервисы были немного «толще», чем мелкие объекты прошлого, поэтому их было меньше, но они всё равно присутствовали. Цикл обратной связи тоже ухудшился: во времена «монолита с XML» редактор XML почти всегда позволял справляться с задачей, а быстрая локальная компиляция и запуск обеспечивали практически полную уверенность в работоспособности конфигурации. Однако от XML все отказались в пользу таких штук, как JSON, Yaml, HCL, Toml — все они неструктурированы, совершенно не дают понять, посчитает ли компьютер вашу прозу абракадаброй или новой пьесой Шекспира, пока вы не запушите код в какой-нибудь тестовый кластер. Внезапно я ощутил, что вернулся в дни университетской учёбы и взаимодействия с мейнфреймом, но в те времена мы хотя бы владели оборудованием и могли спуститься на самый низ, особенно если ты реализуешь «DevOps» — в основном это означает, что у тебя имелись административные права доступа к «железу».
Микросервисы трудно масштабировать и они очень сложны. Большинству использующих их компаний они не требуются, однако применяемые ими системы и языки программирования бедны возможностями, поэтому это навешивание сложности поверх сложности становится необходимостью. Похоже на то, что вопреки всеобщим утверждениям, у нас нет недостатка в разработчиках ПО, поэтому пустая трата их талантов имеет больший экономический смысл, чем воображаемые затраты на адаптацию более мощных систем программирования. Се ля ви. Цикл обратной связи совершенно разрушен — тестирование микросервиса подобно проверке единственной шестерёнки в машине, не гарантирующей, что эта шестерёнка подойдёт к машине — мы просто вбрасываем в решение проблемы больше программистов, ведь Gartner говорит нам, что таково будущее.
Сейчас мы находимся на следующем этапе этой игры: поддержка этих очень сложных систем трудна и не является нашим основным бизнесом, поэтому выведем её на аутсорс (если системы упростить, то придётся сокращать слишком много менеджеров, так что это не вариант). Так родилось Облако, поначалу как маркетинговое название старой бизнес-модели (услуг «виртуальных частных серверов»), но сейчас это всё больше становится маркетинговым названием ещё более старой бизнес-модели (мейнфрейма — мы его обслуживаем, мы им владеем, вы арендуете мощности).
Очевидно, чем хуже, тем лучше, и виртуальные частные серверы тоже можно ухудшить — после краткого экскурса в контейнеризацию микросервисов с их размещением в распределённой системе управления наподобие Mesos, Nomad и Kubernetes мы пришли к «Serverless». Мы размещаем отдельные функции без отслеживания состояния. Но не внутри Java-монолита, ведь эта технология уже стара, а поверх распределённой системы. Если бы вы предложили подобное в 2000 году, вас бы засмеяли, и вас должны были бы засмеять в 2020 году, но такова сила маркетинга. Итак, что у нас есть сегодня? Кодовая база «monorepo» (очевидно, потому, что Git-репозиторий для каждой функции системы был бы перебором), большой дескриптор развёртывания для каждого мелкого компонента, который в Spring, вероятно, назывался бы «контроллером», но тут зовётся «функцией». И вместо того, чтобы комбинировать их все на своём компьютере, ты отправляешь их на чужой мега-мейнфрейм. Развёртываешь систему, получаешь сообщение об ошибке и входишь в CloudWatch, чтобы понять, что же произошло — всё это выполняется пакетно, как в старые недобрые времена, поэтому процесс идёт медленно. По крайней мере, нам не приходится каждый раз бегать к принтеру, но это довольно красноречиво характеризует прогресс за прошедшие полвека. А, да, и ещё «функция» способна одновременно обрабатывать только один запрос, нам нужно много инстансов, так что получите свой счёт за хостинг AWS — надеюсь, вас не хватит удар. Да, мы обрабатываем нагрузки, с которыми бы справился ваш племянник на своём Raspberry Pi 4, но таково будущее энтерпрайза.
Разумеется, история повторяется. Концептуально, сокрытие всех внутренних механизмов масштабирования и координирования — не такая уж плохая идея; такие системы программирования, как Erlang и OTP, уже десятки лет назад показали, насколько хорошо это может работать, а Elixir обеспечил платформе совершенно заслуженный всплеск популярности. Но здесь есть большая разница: платформа наподобие OTP способна выполнять почти всё, что умеет AWS Lambda, но реализует это в единственном языке программирования. Доступны все необходимые инструменты: можно рефакторизировать код на Erlang, можно написать макрос на Elixir, чтобы система оставалась чистой, пластичной и защищённой от случайного появления сложности.
Это называется «Configuration as Code» («конфигурация как код») и является действительно отличной идеей (но едва ли новой). Однако XML — это не код, как не является им ни JSON, ни YAML, ни HCL. У всех этих языков разметки отсутствует необходимое качество, и это становится причиной программирования копипастингом, который я сегодня наблюдаю повсюду, будь то развёртывание на Nomad или использование Terraform/CloudFormation, чтобы состряпать мегасложные кластеры для запуска маркетингового сайта. Такой уровень сложности не может поддерживать себя самостоятельно, и я боюсь, что данная проблема будет решена примерно так, как наша отрасль любит решать создаваемые себе проблемы: добавлением поверх неё ещё большей сложности… А не возвратом к корням и пониманию причин возникновения революции персональных компьютеров. И это очень печально.
На правах рекламы
Нет желания разбираться с инстантами, AWS и прочими радостями микросервисов? Арендуйте надёжный сервер у нас, на котором можете всё запускать как вам вздумается. Используем новейшие процессоры AMD Epyc. Гибкие тарифы — от 1 ядра CPU до безумных 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe.