Serverless
Thomas StormИтак, у нас есть монолиты, микросервисная архитектура, и теперь облачные провайдеры открыто толкают Serverless Framework.
Про монолитную структуру говорить особо нечего. Те, кто успел побывать в махровом энтерпрайзе, государственных структурах или банках, прекрасно понимают, что это такое. Кому “повезло” не влезть в это, поздравляю - вы пропустили целую эпоху, которая была до этих ваших докеров, куберов, ажилей, скрамов, канбанов и дивапсов. Скорее всего, вы даже молоды и красивы.
С микросервисами все немного проще. В большинстве случае это правильно (или неправильно) разбитые монолиты, общающиеся между собой через API, RPC или MQ.
Если одним из главных преимуществ монолита является производительность (если его правильно приготовить, разумеется), то у микросервисов - относительная простота разработки и скорость доставки (опять же, если правильно приготовить). Выкатить маленький контейнер, особенно если в новом релизе нет breaking changes, таких как изменения API или структуры сообщений для MQ, проще и быстрее чем разворачивать огромную монолитную махину.
Монолит держит в себе большой набор функционала под разные структуры бизнеса.
Микросервисы - разбитые кусочки монолита, каждый из которые покрывает свой домен либо полностью, либо частично (то есть на один домен несколько микросервисов).
Теперь про serverless.
В первую очередь serverless архитектура реализуется только у облачного провайдера. Даже если вы напишете свою обертку под serverless и развернете ее в каком-либо датацентре, вы все равно будете “отвечать” за железо в этом самом ДЦ. Другое дело, если это сделает какой-либо контрагент, в таком случае железо - его проблемы. Особенность serverless в том, что все вопросы инфраструктуры (в том числе и планирование ресурсов, scaling, хранение данных и прочее) отданы на откуп 3rd party.
Во-вторых, если микросервис в одном экземпляре может решать несколько задач, то serverless приложение состоит из нескольких функций, каждая из которых выполняет одну и только одну задачу.
Давайте рассмотрим такой кейс: допустим вы заказываете что-то в интернет магазине через мобильное приложение. У вас есть мобильный клиент, который выдает вам товары, вы их добавляете в корзину, затем делаете заказ, оплачиваете, получаете подтверждение заказа и чуть позже (или сразу) чек по почте.
В “безсерверной” модели это может выглядеть следующим образом (на примере AWS вестимо):
- Мобильное приложение делает API вызов через API GW, запуская Lambda.
- Lambda проверит наличие товара (если этого не было сделано) и отправит приложению ответку, что товар добавлен.
- В приложении вы видите, что товар добавлен в корзину. Переходите в корзину и нажимаете оплатить.
- В меню доставки записываете необходимые данные: адрес и прочее.
- Мобильное приложение запускает другую Lambda, которая обрабатывает входные данные и отправляет сообщение в SQS. Получив ответ, что сообщение успешно записано в очередь, возвращает приложение ответку.
- Приложение направляет вас в меню оплаты, вы записываете все необходимые детали (метод оплаты, номер карты и тд).
- Приложение вызывает уже третью Lambda, перенаправляя вас на страницу платежа, например, онлайн банка. Запущенная Lambda отправляет сообщение о формировании счета в SQS.
- Под капотом у интернет магазина запускаются еще две функции: одна обрабатывает входящее сообщение для службы доставки и записывает заказ в БД, вторая, когда оплата будет пройдена, генерирует оплаченный счет, например в PDF, кладет его на S3, берет id объекта, отправляет сообщение в еще одну очередь SQS с содержание почты заказчика и id объекта.
- Финальная функция видит появление сообщения в SQS, возьмет объект из S3 и отправит вам счет по почте с помощью SES.
Помимо этого, конечно, же будут выполняться всякие транзакционные приложения, записи в хранилище данных и т.д.
Звучит немного сложно. На деле у нас получается: несколько Lambda функций, один или несколько API Gateway, несколько очередей SQS, таблиц DynamoDB, бакетов S3.
В моей предыдущей конторе эта структура отрабатывала за максимум 5 минут (бОльшая часть времени уходило на получение информации от местной платежной системы iDeal), спокойно выдерживая >45000 заказов в день.
Ключевой момент здесь - у вас буквально нет ни одного сервера или RDS instance под непосредственным управлением, что и делает ваше приложение “безсерверным”. Еще одно отличие от микросервисов: Lambda не запущены до тех пор, пока им нечего делать, в то время как микросервисы включены 24/7 (за исключением scheduled jobs)
По AWS’ной Serverless Application Model (Cloudformation-совместимые шаблоны ресурсов для приложений) под это определение попадают следующие сервисы и ресурсы: API Gateway, Lambda, Cognito, DynamoDB, Cloudwatch и Cloudwatch Logs, Kinesis, S3, SQS и SNS.
Это не имеет прямого отношения к Serverless Framework, просто Амазон хочет заработать побольше денег и потому решает за вас, какие сервисы относятся к serverless, а какие нет. Если включить зануду, то контейнеры в Fargate - это serverless (у вас нет kubernetes кластера под управлением), SES - тоже.
Вот в общем-то и все. Если немного посмотреть в будущее, то нужно будет еще лет 5-6 на адаптацию этой модели (люди только только к куберу привыкли, вы что), но крупный сектор, где риск > скорости доставки, продолжит пилить монолиты, что в принципе и не плохо.