Советы и источники информации для создания бессерверных приложений
Хотя бессерверные технологии в последние годы быстро набирают популярность, с ними всё ещё связано много заблуждений и опасений. Зависимость от вендора, инструментарий, управление расходами, холодный старт, мониторинг и жизненный цикл разработки — все эти темы активно обсуждаются, когда речь заходит о бессерверных технологиях. В этой статье мы рассмотрим некоторые из упомянутых тем, а также поделимся советами и ссылками на полезные источники информации, с помощью которых новички смогут создать мощные, гибкие и экономичные бессерверные приложения.
Заблуждения относительно бессерверных технологий
Многие считают, что бессерверность и внесерверная обработка данных (Functions as a Service, FaaS) — это почти одно и то же. Значит, разница не слишком велика и стоит внедрить новинку. Хотя AWS Lambda была одной из «звёзд» расцвета бессерверных технологий и одним из самых популярных элементов бессерверной архитектуры, однако эта архитектура представляет собой нечто большее, чем FaaS.
Основной принцип бессерверных технологий заключается в том, что вам не нужно заботиться об управлении и масштабировании инфраструктуры, вы платите только за то, чем пользуетесь. Под эти критерии подходит множество сервисов — AWS DynamoDB, S3, SNS или SQS, Graphcool, Auth0, Now, Netlify, Firebase и многие другие. В целом, бессерверность подразумевает использование всех возможностей облачных вычислений без необходимости управления инфраструктурой и её оптимизации ради масштабирования. Также это означает, что безопасность на уровне инфраструктуры больше не ваша проблема, а это огромное преимущество, учитывая трудность и сложность соблюдения стандартов безопасности. Наконец, вам не нужно покупать предоставленную вам в пользование инфраструктуру.
Бессерверность можно считать «состоянием разума»: определённой ментальностью при проектировании решений. Избегайте подходов, требующих обслуживания любой инфраструктуры. При бессерверном подходе мы тратим время на решение задач, которые непосредственно влияют на проект и приносят выгоду для наших пользователей: создаём устойчивую бизнес-логику, развиваем пользовательские интерфейсы и разрабатываем адаптивные и надёжные API.
К примеру, если можно избежать управления и сопровождения платформы свободного текстового поиска, то именно так мы и поступим. Такой подход к сборке приложений способен сильно ускорить вывод продукта на рынок, ведь вам не нужно больше думать об управлении сложной инфраструктурой. Избавляйтесь от обязанностей и расходов на управление инфраструктурой и сосредоточьтесь на создании приложений и сервисов, которые нужны вашим клиентам. Патрик Дебуа назвал такой подход ‘servicefull’, этот термин принят в бессерверном сообществе. Функции нужно рассматривать как связующее звено для сервисов в виде развёртываемых модулей (вместо развёртывания целой библиотеки или веб-приложения). Это обеспечивает невероятную гранулярность управления развёртыванием и изменениями в приложении. Если вы не можете таким образом развёртывать функции, то это может говорить о том, что функции выполняют слишком много задач и должны быть отрефакторены.
Некоторых смущает зависимость от вендора при разработке облачных приложений. То же самое и с бессерверными технологиями, и вряд ли это следствие заблуждения. По нашему опыту, создание бессерверных приложений на AWS в сочетании со способностью AWS Lambda объединять другие AWS-сервисы — всё это отчасти и формирует достоинства бессерверных архитектур. Это хороший пример синергии, когда результат объединения получается больше, чем просто сумма слагаемых. Пытаясь избежать зависимости от вендора, вы можете столкнуться с ещё большими проблемами. При работе с контейнерами проще управлять собственным уровнем абстракции между облачными провайдерами. Но когда речь заходит о бессерверных решениях, усилия не будут окупаться, особенно если с самого начала учитывать экономическую эффективность. Обязательно выясните, как вендоры обеспечивают предоставление услуг. Некоторые специализированные сервисы зависят от точек интеграции с другими вендорами, и из коробки могут предоставлять возможность подключения в стиле plug-and-play. Проще обеспечить вызов Lambda из конечной точки API шлюза, чем проксировать запрос в какой-то контейнер или экземпляр EC2. Graphcool обеспечивает простое конфигурирование с помощью Auth0, а это проще, чем использовать сторонние средства аутентификации.
Выбор правильного вендора для вашего бессерверного приложения — это решение архитектурного уровня. При создании приложения вы не рассчитываете, что однажды вернётесь к управлению серверами. Выбор облачного вендора ничем не отличается от выбора использования контейнеров или базы данных, или даже языка программирования.
Обдумайте:
- Какие сервисы вам нужны и почему.
- Какие сервисы предоставляют облачные провайдеры и как вы можете объединить их с помощью выбранного FaaS-решения.
- Какие языки программирования поддерживаются (с динамическим или статическим типизированием, компилируемые или интерпретируемые, какие есть бенчмарки, какая производительность при холодном старте, какова open source-экосистема и т.д.).
- Каковы ваши требования по безопасности (SLA, 2FA, OAuth, HTTPS, SSL и т.д.).
- Как управлять вашим CI/CD и циклами разработки ПО.
- Преимуществами каких решений класса infrastructure-as-code вы можете воспользоваться.
Если вы расширяете имеющееся приложение и инкрементально добавляете бессерверные функции, то это может несколько ограничить доступные возможности. Однако почти все бессерверные технологии предоставляют какие-то API (через REST или очереди сообщений), позволяющие создавать расширения независимо от ядра приложения и с простой интеграцией. Ищите сервисы с понятными API, хорошей документацией и сильным сообществом, и не ошибётесь. Простота интеграции зачастую может быть ключевой метрикой, и, вероятно, это одна из главных причин успеха AWS с тех пор, как в 2015-м вышла Lambda.
Когда полезна бессерверность
Бессерверные технологии можно применять практически везде. Однако их достоинства не ограничиваются одними лишь способами применения. Порог входа для облачных вычислений сегодня так низок именно благодаря бессерверным технологиям. Если у разработчиков есть идея, но они не знают, как управлять облачной инфраструктурой и оптимизировать расходы, то им не нужно искать какого-то инженера для этого. Если стартап хочет создать платформу, но опасается, что расходы могут выйти из-под контроля, он легко может обратиться к бессерверным решениям.
Благодаря экономии расходов и простоте масштабирования, бессерверные решения одинаково применимы как для внутренних систем, так и для внешних, вплоть до веб-приложения с многомиллионной аудиторией. Счета измеряются скорее не в евро, а в центах. Аренда самого простого экземпляра AWS EC2 (t1.micro) в течение месяца обойдётся в €15, даже если вы ничего с ним не делаете (кто ни разу не забывал выключить?!). Для сравнения, чтобы достичь такого уже уровня расходов за тот же период времени, вам потребуется запустить Lambda размером 512 Мб на 1 секунду примерно 3 миллиона раз. А если вы не используете эту функцию, то ничего не платите.
Так как бессерверная технология зависит преимущественно от событий, можно довольно легко добавить в старые системы бессерверную инфраструктуру. Например, с помощью AWS S3, Lambda и Kinesis вы можете создать аналитический сервис для старой розничной системы, который сможет получать данные через API.
Большинство бессерверных платформ поддерживают разные языки. Чаще всего это Python, JavaScript, C#, Java и Go. Обычно во всех языках нет никаких ограничений по использованию библиотек, так что можете применять свои любимые open source-библиотеки. Однако желательно не злоупотреблять зависимостями, чтобы ваши функции выполнялись оптимально и не обнуляли преимущества огромной масштабируемости ваших бессерверных приложений. Чем больше пакетов нужно загрузить в контейнер, тем дольше будет выполняться холодный запуск.
Холодный запуск — это когда необходимо сначала инициализировать контейнер, среду исполнения и обработчик ошибок, прежде чем ими пользоваться. Из-за этого задержка выполнения функций может достигать 3 секунд, а это не лучший вариант для нетерпеливых пользователей. Однако холодные запуски бывают при первом обращении спустя несколько минут простоя функции. Так что многие считают это незначительным неудобством, которое можно обойти с помощью регулярного пингования функции, чтобы поддерживать ее на холостом ходу. Или вообще игнорируют этот аспект.
Хотя AWS выпустила бессерверную SQL-базу данных Serverless Aurora, всё же SQL-базы не идеальны для подобного применения, ведь при выполнении транзакций они зависят от подключений, которые могут быстро стать узким местом при большом трафике на AWS Lambda. Да, разработчики постоянно улучшают Serverless Aurora, и вам стоит поэкспериментировать с ней, однако сегодня для бессерверных систем гораздо лучше подходят NoSQL-решения вроде DynamoDB. Впрочем, несомненно, что эта ситуация очень скоро изменится.
Инструментарий тоже накладывает немало ограничений, особенно в сфере локального тестирования. Хотя и существуют решения вроде Docker-Lambda, DynamoDB Local и LocalStack, однако они требуют кропотливой работы и значительного объёма конфигурирования. Впрочем, все эти проекты активно развиваются, так что это лишь вопрос времени, когда инструментарий достигнет необходимого нам уровня.
Влияние бессерверных технологий на цикл разработки
Поскольку ваша инфраструктура представляет собой просто конфигурацию, можно задать и развернуть код с помощью скриптов, например, shell-скриптов. Или можно прибегнуть к решениям класса configuration-as-code вроде AWS CloudFormation. Хотя этот сервис и не предоставляет конфигурацию для всех сфер, но зато позволяет определять конкретные ресурсы для использования в качестве Lambda-функций. То есть там, где CloudFormation вас подведёт, вы можете написать свой ресурс (Lambda-функцию), который закроет эту брешь. Таким образом вы можете сделать что угодно, даже сконфигурировать зависимости за пределами вашего AWS-окружения.
Поскольку всё это просто конфигурация, вы можете параметризовать ваши скрипты развёртывания под конкретные окружения, регионы и пользователей, особенно если применяете решения класса infrastructure-as-code вроде CloudFormation. Например, вы можете развернуть копию инфраструктуры для каждой ветки в репозитории, чтобы полностью изолированно тестировать их в ходе разработки. Это радикально ускоряет получение разработчиками обратной связи, когда хотят понять, адекватно ли работает их код в живом окружении. Руководителям не нужно беспокоиться о стоимости развёртывания многочисленных окружений, ведь оплачивается только фактическое использование.
У DevOps становится меньше забот, поскольку им нужно лишь удостовериться, что у разработчиков корректная конфигурация. Больше не нужно управлять инстансами, балансировщиками или группами безопасности. Поэтому всё чаще применяют термин NoOps, хотя всё ещё важно уметь конфигурировать инфраструктуру, особенно когда речь идёт об IAM-конфигурации и оптимизации облачных ресурсов.
Есть очень мощные инструменты для мониторинга и наглядного представления вроде Epsagon, Thundra, Dashbird и IOPipe. Они позволяют отслеживать текущее состояние бессерверных приложений, предоставляют журналы и трассировку, регистрируют метрики производительности и узкие места архитектуры, выполняют анализ и прогнозирование расходов, и многое другое. Они не только дают DevOps-инженерам, разработчикам и архитекторам исчерпывающее представление о работе приложений, но и позволяют руководителям отслеживать ситуацию в реальном времени, с посекундными расходами на ресурсы и прогнозированием затрат. Организовать такое с управляемой инфраструктурой гораздо труднее.
Проектировать бессерверные приложения значительно проще, потому что вам не нужно развёртывать веб-серверы, управлять виртуальными машинами или контейнерами, патчить серверы, операционные системы, интернет-шлюзы и т. д. Абстрагирование от всех этих обязанностей позволяет бессерверной архитектуре сосредоточиться на главном — на решении потребностей бизнеса и клиентов.
Хотя инструментарий мог быть и лучше (он улучшается с каждым днём), однако разработчики могут сосредоточиться на реализации бизнес-логики и наилучшем распределении сложности приложения по разным сервисам в пределах архитектуры. Управление бессерверными приложениями выполняется на основе событий и абстрагировано облачным провайдером (например, SQS, S3-события или DynamoDB-потоки). Поэтому разработчикам достаточно лишь прописать бизнес-логику для реакции на определённые события, и можно не беспокоиться о том, как лучше реализовать базы данных и очереди сообщений, или как организовать оптимальную работу с данными в конкретных аппаратных хранилищах.
Код можно выполнять и отлаживать локально, как и при любом процессе разработки. Модульное тестирование остаётся прежним. Возможность развёртывать целую инфраструктуру приложения с помощью настраиваемой конфигурации стека позволяет разработчикам быстро получать важную обратную связь, не думая о стоимости тестирования или о влиянии на дорогие управляемые окружения.
Инструменты и методики сборки бессерверных приложений
Не существует конкретного способа сборки бессерверных приложений. Как и набора сервисов для этой задачи. Лидером среди мощных бессерверных решений сегодня является AWS, однако обратите внимание ещё на Google Cloud, Zeit и Firebase. Если вы используете AWS, то в качестве подхода к сбору приложений можно порекомендовать Serverless Application Model (SAM), особенно при использовании C#, поскольку в Visual Studio прекрасный инструментарий. SAM CLI может делать всё то же самое, что и Visual Studio, так что вы ничего не потеряете, если перейдёте на другой IDE или текстовый редактор. Конечно, SAM работает и с другими языками.
Если вы пишете на других языках, то Serverless Framework — превосходный open source-инструмент, позволяющий сконфигурировать что угодно с помощью очень мощных конфигурационных YAML-файлов. Также Serverless Framework поддерживает различные облачные сервисы, поэтому рекомендуем его тем, кто ищет мультиоблачное решение. У него огромное сообщество, создавшее кучу плагинов под любые нужды.
Для локального тестирования хорошо подходят open source-инструменты Docker-Lambda, Serverless Local, DynamoDB Local и LocalStack. Бессерверные технологии пока ещё находятся в ранней стадии развития, как и инструментарий для них, так что при настройке под сложные сценарии тестирования придётся попотеть. Однако просто развернуть стек в окружении и протестировать там получается невероятно дёшево. И вам не нужно делать точную локальную копию облачных окружений.
Для уменьшения размеров развёрнутых пакетов и ускорения загрузки используйте AWS Lambda Layers.
Используйте для конкретных задач правильные языки программирования. У разных языков свои достоинства и недостатки. Существует много бенчмарков, но JavaScript, Python и C# (.NET Core 2.1+) — лидеры с точки зрения производительности AWS Lambda. Недавно в AWS Lambda появился Runtime API, который позволяет указывать желаемый язык и среду исполнения, так что экспериментируйте.
Поддерживайте маленький размер пакетов для развёртывания. Чем они меньше, тем быстрее загружаются. Избегайте использования больших библиотек, особенно если используете из них пару фич. Если программируете на JavaScript, то используйте инструменты для сборки вроде Webpack, чтобы оптимизировать сборку и включать только то, что вам действительно нужно. В .NET Core 3.0 есть QuickJit и Tiered Compilation, которые улучшают производительность и сильно помогают при холодных запусках.
Зависимость бессерверных функций от событий поначалу может затруднить координирование бизнес-логики. В связи с этим невероятно полезными могут быть очереди сообщений и конечные автоматы. Lambda-функции способны вызывать друг друга, но делайте это только в том случае, если не ожидаете получения ответа («выстрелил и забыл») — вы же не хотите получать счёт за ожидание завершения другой функции. Очереди сообщений полезны для обособления частей бизнес-логики, управления узкими местами приложений и обработки транзакций (с помощью FIFO-очередей). Функции AWS Lambda могут быть приписаны к SQS-очередям в качестве очередей «зависших» сообщений, которые отслеживают сбойные сообщения для последующего анализа. Функции AWS Step Functions (конечные автоматы) очень полезны для управления сложными процессами, требующими создания цепочек функций. Вместо того чтобы Lambda-функция вызывала другую функцию, Step-функции могут координировать переходы состояний, передавать данные между функциями и управлять глобальным состоянием функций. Это позволяет определять условия повторных попыток, или что нужно делать при возникновении конкретной ошибки — в определённых условиях очень мощный инструмент.
Заключение
В последние годы бессерверные технологии развиваются невиданными темпами. С этой сменой парадигмы связаны определённые заблуждения. Благодаря абстрагированию инфраструктуры и управления масштабированием бессерверные решения предлагают значительные выгоды: от упрощения разработки и DevOps-процессов, до большого снижения операционных расходов.
И хотя бессерверный подход не лишён недостатков, однако существуют надёжные методики паттерны проектирования, с помощью которых можно создать устойчивые бессерверные приложения или интегрировать бессерверные элементы в имеющиеся архитектуры.