Serverless и React 2: ловкость рук и никакого мошенничества

в 9:58, , рубрики: javascript, ReactJS, serverless, Блог компании JUG.ru Group

Можно ли по-простому рассказать фронтенд-разработчикам о работе «безоблачной» архитектуры Serverless в рамках AWS (Amazon Web Services)? Почему бы и нет. Давайте отрендерим React/Redux-приложение в архитектуре AWS, а после этого поговорим о плюсах и минусах AWS-лямбд.

В основе материала — расшифровка доклада Марины Миронович с нашей весенней конференции HolyJS 2018 в Санкт-Петербурге.

Официально Марина — ведущий разработчик EPAM. Cейчас она работает в solution architect группе у заказчика и из-за этого участвует в большом количестве проектов. Поэтому нам будет проще очертить круг ее нынешних интересов, чем перечислять все те технологии, с которыми она работает.

Serverless и React 2: ловкость рук и никакого мошенничества - 1В первую очередь мне интересны все облачные технологии, в частности, AWS, потому что я с этим очень много работаю в продакшене. Но я стараюсь не отставать от всего остального.

Фронтенд — моя первая любовь и, кажется, навсегда. В частности, сейчас я работаю с React и React Native, поэтому я знаю об этом чуть больше. Также стараюсь следить за всем остальным. Мне интересно всё, что связано с документированием проекта, например, UML-диаграммы. Так как состою в solution architect группе, приходится этим много заниматься.

Часть 1. Предыстория

Идея рассказать о Serverless родилась у меня примерно год назад. Я хотела рассказать о Serverless для фронтенд-разработчиков легко и непринужденно. Чтобы вам не понадобилось никаких дополнительных знаний для его использования, тем более технологии сейчас позволяют это делать.

В какой-то мере идея была реализована — я рассказала о Serverless на FrontTalks 2017. Но оказалось, что для простого и понятного рассказа 45 минут недостаточно. Поэтому доклад был разбит на две части, и сейчас перед вами вторая «серия». Кто не видел первую — не волнуйтесь, это не помешает понять то, что написано ниже. Как в приличных сериалах, я начну с краткого содержания предыдущей части. Затем перейду к самому соку — мы отрендерим React/Redux-приложение. А напоследок я расскажу про плюсы и минусы облачных функций в принципе (в частности, AWS-лямбд) и что с ними еще можно сделать. Я надеюсь, именно эта часть будет полезна всем тем, кто уже знаком с AWS-лямбдой. Самое главное — мир не заканчивается на Amazon, поэтому поговорим и о том, что еще есть в сфере облачных функций.

Что я буду использовать

Чтобы отрендерить приложение, я буду использовать много сервисов Amazon:

  1. S3 — это, считайте, файловая система в облаках. Там мы будем хранить статические ассеты.
  2. IAM (права доступа для пользователей и сервисов) — неявно, но он будет использоваться в бэкграунде, чтобы сервисы общались друг с другом.
  3. API Gateway (URL для доступа к сайту) — вы увидите URL, по которым мы сможем вызвать нашу лямбду.
  4. CloudFormation (для деплоя) — неявно будет использоваться в бекграунде.
  5. AWS Lambda — мы сюда пришли для этого.

Что такое serverless и что такое AWS Lambda?

На самом деле Serverless — большой обман, потому что сервера, конечно же, есть: где-то же все это запускается. Но что там происходит?

Мы пишем функцию, и эта функция запускается на серверах. Конечно же, запускается она не просто так, а в каком-то контейнере. И, собственно, эта функция в контейнере на сервере и называется лямбдой.

Serverless и React 2: ловкость рук и никакого мошенничества - 2

В случае лямбды мы можем забыть о серверах. Я бы даже сказала так: когда вы пишите функцию лямбда, вредно о них думать. Мы работаем с лямбдой не так, как мы работаем с сервером.

Как деплоить лямбду

Возникает логичный вопрос: если у нас нет сервера, как же мы ее деплоим? На сервере есть SSH, мы залили код, запустили — все хорошо. Что делать с лямбдой?

Вариант 1. Мы можем ее не деплоить

AWS в консоли сделал для нас милое и нежное IDE, куда мы можем прийти и прямо там написать функцию.

Serverless и React 2: ловкость рук и никакого мошенничества - 3

Это мило, но не очень расширяемо.

Вариант 2. Мы можем сделать zip и загрузить его из командной строки

Как мы делаем zip-файл?

zip -r build/lambda.zip index.js [node_modules/] [package.json]

Если вы используете node_modules, все это зипуется в один архив.
Дальше в зависимости от того, создаете ли вы новую функцию или такая функция у вас уже есть, вы делаете либо

aws lambda create-function...

либо

aws lambda update-function-code...

В чем проблема? Во-первых, AWS CLI хочет знать, создается ли функция или она у вас уже есть. Это две разные команды. Если вы хотите обновлять не только код, но и какие-то атрибуты этой функции, начинаются проблемы. Количество этих команд разрастается, и вам надо сидеть со справочником и думать, какую команду использовать.

Мы можем это сделать лучше и проще. Для этого у нас есть фреймворки.

Фреймворки для AWS Lambda

Таких фреймворков много. В первую очередь это AWS CloudFormation, который работает в связке с AWS CLI. CloudFormation — это Json-файл описания ваших сервисов. Вы их описываете в Json-файле, потом черезе AWS CLI говорите «выполнить», и она автоматически создаст все для вас в AWS-сервисе.

Но это все равно еще сложно для такой простой задачи, как отрендерить что-то. Тут слишком большой порог входа — надо почитать, какая структура у CloudFormation и т.п.

Попробуем еще упростить. И здесь появляются разные фреймворки: APEX, Zappa (только для Python), Claudia.js.  Я перечислила лишь некоторые, случайным образом.

Проблема и сила этих фреймворков в том, что они узкоспециализированные. Значит, они очень хорошо делают какую-то простую задачу. Например, Claudia.js очень хороша для создания REST API. Она сделает AWS call API Gateway, она создаст для вас лямбду, это все красиво задеплоится. Но если вам надо задеплоить чуть больше, начинаются проблемы — приходится что-то дописывать, помогать, искать и т.д.

Zappa написали только для Python. А хочется чего-то более масштабного. И тут приходят Terraform и моя любовь Serverless.

Serverless находится где-то посередине между очень большим CloudFormation, который умеет делать почти все, и этими узкоспециализированными фреймворками. В нем можно деплоить почти все, но делать все это еще достаточно легко. Кроме того, у него очень легкий синтаксис.

Terraform —  в какой-то мере аналог CloudFormation. Terraform — это open source, в нем можно деплоить все — ну или почти все. А когда AWS создает сервисы, там можно добавлять что-то новое. Но он большой и сложный.

Если честно, в продакшене мы используем Terraform, потому что с Terraform все, что у нас есть, поднимается легче — Serverless все это не опишет. Но Terraform очень сложный. И когда я пишу что-то для работы, я сначала пишу это на Serverless, тестирую на работоспособность и только после того, как моя конфигурация оттестирована и отработана, я переписываю на Terraform (это «развлечение» еще на пару дней).

Serverless

Почему я люблю Serverless?

  1. В Serverless есть система, которая позволяет создавать плагины. По-моему, это спасение от всего. Serverless — open source. Но дописать что-то в open source не всегда легко. Нужно понять, что происходит в существующем коде, соблюдать гайдлайны, как минимум codestyle, засабмиттить PR, про этот PR забудут и он будет пылиться три года. По итогам вы форкните, и это у вас будет лежать где-то отдельно. Все это не очень здорово. Но когда есть плагины, все упрощается. Надо что-то дописать — вы на коленке создаете свой маленький плагин. Для этого больше не надо разбираться в том, что происходит внутри Serverless (если это не супер-кастомный вопрос). Вы просто используете доступный API, где-то у себя сохраняете плагин или деплоите его для всех. И у вас все работает. Кроме того, уже есть большой зоопарк плагинов и людей, которые пишут эти плагины. То есть, возможно, что-то уже решили за вас.
  2. Serverless помогает запускать лямбду локально. Достаточно большой минус лямбды в том, что AWS не думал, как мы будем ее дебажить и тестировать. А вот Serverless позволяет запустить все локально, посмотреть, что происходит (он даже это делает в связке с API Gateway).

Демонстрация

Сейчас я покажу, как все это работает на самом деле. За следующие полторы-две минуты мы сможем создать сервис, который отрендерит нашу HTML-страницу.
Сначала в новой папке я запущу SLS Create template:


mkdir sls-holyjs
cd sls-holyjs
sls create --template aws-nodejs-ecma-script

Serverless и React 2: ловкость рук и никакого мошенничества - 4

npm install

Serverless и React 2: ловкость рук и никакого мошенничества - 5

Разработчики Serverless позаботились о нас — сделали возможность создавать сервисы из темплейтов. В данном случае я использую темплейт nodejs-ecma-script, который создаст для меня некоторые файлы, такие как webpack-конфигурацию, package.json, некоторые функции и serverless.yml:

ls

Serverless и React 2: ловкость рук и никакого мошенничества - 6

Мне не нужны все функции. Я удалю первую, вторую переименую в holyjs:

Serverless и React 2: ловкость рук и никакого мошенничества - 7

Немного подправлю serveless.yml, где у меня происходит описание всех необходимых сервисов:

Serverless и React 2: ловкость рук и никакого мошенничества - 8

Ну и затем исправлю тот response, который возвращает функция:

Serverless и React 2: ловкость рук и никакого мошенничества - 9

Сделаю HTML «Hello HolyJS» и добавлю handle для рендеринга.

Далее:

sls deploy

И вуаля! Есть URL, по которому я смогу в public-доступе посмотреть, что у меня рендерится:

Serverless и React 2: ловкость рук и никакого мошенничества - 10

Доверяй, но проверяй. Я пойду в AWS Console и проверю, что у меня создалась holyjs-функция:

Serverless и React 2: ловкость рук и никакого мошенничества - 11

Как видите, перед тем, как ее задеплоить, Serverless соберет ее с помощью webpack. Кроме этого, создастся вся остальная инфраструктура, которая там описана — API Gateway и т.д.

Когда я захочу это удалить:

sls remove

Удалится вся инфраструктура, которая описана в serverless.yml.

Serverless и React 2: ловкость рук и никакого мошенничества - 12

Если кто-то отстал от описанного здесь процесса, я приглашаю просто пересмотреть мой предыдущий доклад.

Запускаем лямбду локально

Я упоминала, что лямбду можно запустить локально. Здесь есть два варианта запуска.

Вариант 1. Мы просто запустим все в терминале

Получим то, что возвращает наша функция.


sls invoke local -f [fn_name]

Вариант 2. Запускаем лямбду локально serverless-offline

Не забываем, мы делаем изоморфное приложение, это будет HTML и CSS, поэтому в терминале как-то не очень интересно смотреть на длинные HTML строки. Там можно проверить, что функция работает. Но я хотела бы запустить и отрендерить это в браузере. Соответственно, мне нужна связка API gateway с лямбдой.

Для этого есть отдельный плагин serverless-offline, который запустит вашу лямбду на каком-нибудь порту (это прописывается), затем выведет в терминал URL, по которому вы сможете получить к ней доступ.

sls offline --port 8000 start

Самое приятное, что здесь есть hot reloading. То есть вы пишете код функции, обновляете ваш браузер и у вас обновляется то, что возвращает функция. Вам не надо перезапускать все.

Это было краткое содержание первой части доклада. Теперь мы переходим к основной части.

Часть 2. Рендеринг с помощью AWS

Описанный ниже проект уже находится на GitHub. Если вам интересно, там можно скачать код.

Давайте начнем с того, как все это работает.

Serverless и React 2: ловкость рук и никакого мошенничества - 13

Предположим, есть пользователь — я.

  • Я открываю сайт.
  • По некому URL мы обращаемся к API gateway. Хочу заметить, что API Gateway — это уже сервис AWS, мы уже находимся в облаках.
  • API Gateway вызовет лямбду.
  • Лямбда отрендерит сайт, и все это вернется в браузер.
  • Браузер начнет рендерить и поймет, что не хватает каких-то статических файлов. Тогда он обратится к S3 bucket (нашей файловой системе, где мы будем хранить всю статику; в S3 bucket можно класть все — шрифты, картинки, CSS, JS).
  • Данные из S3 bucket вернутся в браузер.
  • Браузер отрендерит страницу.
  • Все счастливы.

Давайте сделаем небольшой code review того, что я написала.

Если вы зайдете на GitHub, то увидите такую структуру файлов:

lambda-react
README.md
config
package.json

public
scripts
serverless.yml
src

yarn.lock

Все это сгенерировано автоматически в React/Redux tool kit. На самом деле, здесь нам будет интересна буквально пара файлов и их придется немного подправить:

  • config
  • package.json
  • serverless.yml — потому что мы будем деплоить,
  • src — без этого никуда.

Начнем с конфигурации

Чтобы у нас все собралось на сервере, нам надо добавить еще один webpack.config:

Serverless и React 2: ловкость рук и никакого мошенничества - 14

Этот webpack.config уже будет для вас сгенерирован, если вы используете template. И там автоматически подставится переменная slsw.lib.entries, которая будет указывать на ваши лямбда-хендлеры. Если хотите, вы можете ее изменить сами, указав что-то другое.

Serverless и React 2: ловкость рук и никакого мошенничества - 15

Нам надо будет все отрендерить для нода ( target: ‘node’). В принципе все остальные лоадеры остаются теми же, что и для обычного React приложения.

Дальше в package.json

Мы просто добавим пару скриптов — start и build уже были сгенерированы с React/Redux — ничего не меняется. Добавим скрипт, чтобы запустить лямбду, и скрипт, чтобы деплоить лямбду.

Serverless и React 2: ловкость рук и никакого мошенничества - 16

serverless.yml

Очень маленький файл — всего 17 строк, все они ниже:

Serverless и React 2: ловкость рук и никакого мошенничества - 17

Что нам в нем интересно? В первую очередь handler. Там прописывается полный путь до файла (src/lambda/handler) и через точку указывается функция handler.

Если очень хочется, в одном файле можно прописать несколько хэндлеров. Еще здесь прописан путь до webpack, который должен это все собирать. В принципе все: остальное уже сгенерировано автоматически.

Самое интересное — это src

Здесь огромное React/Redux приложение (в моем случае оно не огромное — на страничку). В дополнительной папке lambda находится все, что нам надо, чтобы отрендерить лямбду:

Serverless и React 2: ловкость рук и никакого мошенничества - 18

Это 2 файла:

Serverless и React 2: ловкость рук и никакого мошенничества - 19

Давайте начнем с handler. Самое важное — 13 строка. Это рендерер, который является той самой лямбдой, что будет вызываться в облаках:

Serverless и React 2: ловкость рук и никакого мошенничества - 20

Как видите, функция render () возвращает promise, с которого обязательно надо словить все исключения. В этом особенности работы лямбды, иначе лямбда не закончится сразу, а будет работать до таймаута. Вам придется платить лишние деньги за код, который уже упал. Чтобы этого не случилось, надо закончить работу лямбды как можно раньше — в первую очередь, словить и обработать все исключения. Позже мы к этому еще вернемся.

Если у нас нет никаких ошибок и исключений, мы вызываем функцию createResponse, которая занимает буквально пять строк. Мы просто добавим все хедеры, чтобы она правильно отрендерилась в браузере:

Serverless и React 2: ловкость рук и никакого мошенничества - 21

Здесь самое интересное — функция render, которая отрендерит нашу страницу:

Serverless и React 2: ловкость рук и никакого мошенничества - 22

Эта функция приходит к нам из renderer.js. Давайте посмотрим, что там.

Там рендерится изоморфное приложение. При том оно рендерится на любом сервере — здесь не важно, лямбда это или нет.

Не буду подробно рассказывать вам о том, что такое изоморфное приложение, как его отрендерить, потому что это совершенно другая тема, и есть люди, которые рассказали это лучше меня. Вот некоторые туториалы, которые я нашла, погуглив буквально пару минут:

Serverless и React 2: ловкость рук и никакого мошенничества - 23

Если вы знаете какие-то другие доклады, можете посоветовать, я дам на них ссылки у себя в твиттере.

Чтобы никого не терять, я просто пройдусь по верхам, расскажу, что там происходит.
В первую очередь, нам надо с React/Redux отрендерить это в HTML-строку.

Это делается через стандартный метод React — renderToString:

Serverless и React 2: ловкость рук и никакого мошенничества - 24

Дальше мы должны отрендерить стили, чтобы у нас не мигал контент. Это не очень тривиальная задача. Есть несколько npm-пакетов, которые ее решают. Например, я использовала node-style-loader, который соберет все в styleTag, и его потом можно вставить в HTML.

Serverless и React 2: ловкость рук и никакого мошенничества - 25

Если есть пакеты лучше — это на ваше усмотрение.

Дальше нам надо передать Redux state. Раз вы рендерите на сервере, вам, наверное, захочется получить какие-то данные, и вы не хотите, чтобы Redux их снова перезапрашивал и перерендерил. Это достаточно стандартная задача. На основном сайте Redux есть примеры, как это сделать: мы создаем объект и потом через глобальную переменную его передаем:

Serverless и React 2: ловкость рук и никакого мошенничества - 26
Теперь чуть ближе к лямбде.

Надо сделать обработку ошибок. Мы хотим все поймать и что-то с ними сделать, как минимум остановить разработку лямбды. Я, например, сделала это через promise:

Serverless и React 2: ловкость рук и никакого мошенничества - 27

Далее надо подставить наши URL для статических файлов. И для этого нам надо узнать, где запускается лямбда — локально или где-то в облаках. Как это узнать?

Мы будем это делать через переменные среды:


const bundleUrl = process.env.NODE_ENV === 'AWS' ?
AWS_URL : LOCAL_URL;

Интересный вопрос: как сетапятся в лямбде переменные среды. На самом деле достаточно легко. В yml вы можете в environment передать любые переменные. Когда она задеплоится, они будут доступны:

Serverless и React 2: ловкость рук и никакого мошенничества - 28

Ну и бонус — после того, как мы задеплоили лямбду, нам хочется задеплоить все статические ассеты. Для этого уже написали плагин, где можно обозначить ту S3-корзину, куда вы хотите что-то задеплоить:

Serverless и React 2: ловкость рук и никакого мошенничества - 29
Итого мы сделали изоморфное приложение минут за пять, чтобы показать, что это все легко.

Теперь давайте немного поговорим о теории — о плюсах и минусах лямбды.

Начнем с плохого.

Минусы лямбда функций

К минусам может относиться (а может и нет) время холодного старта. Например, для лямбды на Node.js, которую мы сейчас пишем, время холодного старта не так уж много значит.

График ниже показывает время холодного старта. И это может быть big deal особенно для Java и C# (обратите внимание на оранжевые точки) — вы не хотите, чтобы у вас пять-шесть секунд занимало только начало выполнения кода.

Для Node.js время старта — почти ноль — 30 — 50 мс. Конечно, для кого-то это тоже может быть проблемой. Но функции можно разогревать (хотя это не тема данного доклада). Если кому-то интересно, как проводились эти тесты, добро пожаловать на acloud.guru, они все расскажут (в статье).

Serverless и React 2: ловкость рук и никакого мошенничества - 30

Так все же какие минусы?

Ограничения по размеру кода функции

Код должен быть меньше 50 Мб. Можно ли написать такую большую функцию? Прошу не забывать про node_modules. Если вы будете что-то подключать, особенно если там есть бинарные файлы, вы действительно можете легко перейти за 50 МБ, даже для zip-файлов. У меня были такие случаи. Но это дополнительный повод посмотреть, что вы подключаете в node_modules.

Ограничения по времени выполнения

По дефолту функция выполняется секунду. Если она не закончится через секунду, у вас будет таймаут. Но это время можно увеличить в настройках. При создании функции можно установить значение до пяти минут. Пять минут — это hard deadline. Для сайта это не проблема. Но если вы захотите на лямбдах сделать что-нибудь поинтереснее, например, обработку изображений, перевод текста в звук или звука в текст и т.д., такие вычисления легко могут занять больше пяти минут. И это будет проблема. Что с этим делать? Оптимизировать или не использовать лямбду.

Еще одна интересная штука, которая возникает в связи с ограничением по времени выполнения лямбды. Вспомним схему нашего сайта. Все работало отлично, пока не пришел product и не пожелал на сайте real time feed — показывать новости в реальном времени. Мы знаем, что это реализуется с WebSocket-ами. Но WebSocket-ы работают не пять минут, их надо держать дольше. И здесь лимит в пять минут становится проблемой.

Serverless и React 2: ловкость рук и никакого мошенничества - 31

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

Количество параллельных функций в минуту

Сверху стоит ограничение от 500 до 3000, в зависимости от того региона, где вы находитесь. По-моему, в Европе почти везде 500. 3000 поддерживается в США.

Если у вас нагруженный сайт и вы ожидаете более трех тысяч запросов в минуту (что легко представить) это становится проблемой. Но до того как поговорить про этот минус, давайте чуть-чуть поговорим про то, как масштабируется лямбда.

К нам приходит запрос, и у нас появляется лямбда. Пока эта лямбда выполняется, к нам приходят еще два запроса — у нас запускаются еще две лямбды. На наш сайт начинают приходить люди, появляются запросы и запускаются лямбды, все больше и больше.

Serverless и React 2: ловкость рук и никакого мошенничества - 32

При этом вы платите за то время, когда выполняется лямбда. Предположим, вы платите один цент за одну секунду выполнения лямбды. Если у вас секунду выполняется 10 лямбд, соответственно вы заплатите 10 центов за эту секунду. Если у вас за секунду выполняется миллион лямбд, это будет уже около 10 тыс. долларов. Неприятная цифра.

Поэтому AWS решил, что они не хотят опустошить ваш кошелек за секунду, если вы неправильно сделали свои тесты и сами себя начинаете DDOS-ить, вызывая лямбды, или вас пришел DDOS-ить кто-то другой. Поэтому было установлено ограничение в три тысячи — чтобы у вас была возможность среагировать на ситуацию.

Если нагрузка в 3000 запросов для вас штатная, можно написать в AWS и они поднимут лимит.

Stateless

Это последний, опять таки, спорный минус.

Что такое stateless? Тут подойдет шутка про золотых рыбок — они просто не держат контекст:

Serverless и React 2: ловкость рук и никакого мошенничества - 33

Лямбда, вызванная второй раз, ничего не знает о первом вызове.

Давайте я покажу это на примере. Допустим, у меня есть система — большой черный ящик. И эта система, кроме всего прочего, умеет отправлять SMS.

Приходит пользователь и говорит: отправь SMS шаблон номер 1. И система отправляет его на реальный девайс.

Serverless и React 2: ловкость рук и никакого мошенничества - 34

В какой-то момент product высказывает пожелание узнать, что там отправится, и проверить, что нигде в этой системе ничего не сломалось. Для этого мы заменим реальный девайс на какой-то тестовый номер — например, это умеет Twilio. Он вызовет Webhook, пришлет текст SMS, мы обработаем этот текст SMS в приложении (нам надо проверить, что наш шаблон стал правильной SMS-кой).

Чтобы проверить, нам надо знать, что было отправлено — это мы сделаем через тестовое приложение. Осталось сравнить и отобразить результаты.

Serverless и React 2: ловкость рук и никакого мошенничества - 35

Давайте попробуем сделать то же самое на лямбде.

Лямбда отправит SMS, SMS придет на Twilio.

Serverless и React 2: ловкость рук и никакого мошенничества - 36

Я нарисовала пунктирную линию не случайно, потому что SMS обратно может дойти через минуты, часы или дни — зависит от вашего оператора, то есть это не синхронный вызов. К этому времени лямбда вообще все забудет, и проверить SMS мы уже не сможем.

Я бы сказала, что это не минус, а особенность. Схему можно переделать. Существует несколько вариантов сделать это, я предложу свой. Если у нас stateless, а мы хотим что-то сохранить, то обязательно надо использовать хранилище, например, базу данных, S3, да что угодно, что будет хранить наш контекст.

В схеме с хранилищем SMS отправится на тестовый номер. И когда Webhook его вызовет — я предлагаю вызывать, например, вторую лямбду, потому что это немного другая функция. И вторая лямбда уже сможет пойти и забрать из базы данных ту SMS-ку, которая отправилась, проверить ее и отобразить результаты.

Serverless и React 2: ловкость рук и никакого мошенничества - 37

Бинго!

В самом начале я говорила, что надо забыть про серверы, если пишешь лямбду. Я встречала людей, которые пишут на node.js и привыкли к express-серверам. Они любят полагаться на кеш, а кэш остается в лямбдах. И иногда, когда они тестируют, это будет работать, а иногда — нет. Как такое возможно?

Предположим, у нас есть сервер, и в нем запускается контейнер. Запуск контейнера — это достаточно дорогая операция. Надо, во-первых, этот контейнер сделать. Только после того, как он будет создан, туда деплоится код функции и она сможет выполниться. После того как ваша функция выполнилась, контейнер не убивается, потому что AWS считает, что вы можете вызвать эту функцию снова. AWS нигде не написал, сколько живет контейнер после того, как функция остановилась. Мы делали эксперименты. По-моему, для node это три минуты, для Java они могут держать контейнер 12-15 минут. Но это значит, что когда придет вызов следующей функции, она вызовется в том же контейнере и в той же среде. Если вы где-то используете node cache — создали там переменные и т.д. — если вы их не почистили, они там и останутся. Поэтому если вы пишите на лямбде, то надо забыть о кеше вообще, иначе можно попасть в неприятные ситуации. Это сложно отдебажить.

Плюсы лямбда-функций

Их меньше, но мне они кажутся более приятными.

  • В первую очередь мы действительно забываем, что есть сервера. Как разработчик, я пишу функцию на javascript, и все. Я уверена, что многие из вас писали функции на javascript-е, вам ничего не надо дополнительно знать об этом.
  • Не надо думать ни о кэше, ни о масштабировании, вертикальном или горизонтальном. То, что вы написали, будет работать. И не важно, на ваш сайт приходит один человек в месяц или там будет миллион посещений.
  • В случае с AWS-лямбды — у них уже есть своя интеграция почти со всеми их серверами (DynamoDB, Alexa, API Gateway, и т. д.).

Что еще можно сделать на лямбдах?

Я привела достаточно стандартный пример — я рассказывала про рендеринг изоморфного приложения, потому что в основном о лямбдах думают, как о REST API. Но я хочу привести еще несколько примеров того, что с ними можно сделать, чтобы просто вам дать пищу для размышлений и фантазии.

В принципе, на лямбдах можно сделать все, что угодно… со звездочкой.

  • HTTP Services — это о чем я говорила. REST API, каждый API endpoint — одна лямбда. Матчится просто идеально. Особенно с учетом того, как в enterprise зачастую используется node.js при создании middleware. У нас есть java, которая делает всю калькуляцию, потом мы пишем на js прослойку, которая очень легко обрабатывает запросы. Ее можно переписать на лямбдах и будет еще круче.
  • IoT — например, у нас Alexa запускает запрос на сервер с каким-то файлом-расшифровкой, а ваш сервер уже на самом деле не сервер, а лямбда.
  • Chat Bots — почти то же самое, как и IoT.
  • Image/Video conversions.
  • Machine learning.
  • Batch Jobs — из-за масштабирования лямбд, любые Batch Job просто идеально на это ложатся.

Сейчас кроме Amazon, Google, Azure, IBM, Twillio — почти все большие сервисы хотят внедрить у себя cloud functions. Если же Роскомнадзор все заблокирует, мы заводим маленький любимый сервер у себя в гараже и деплоим туда наши облачные вычисления. Для этого нам нужен open source (тем более что за сервисы надо платить, а open source — бесплатный). И open source не стоит на месте. Они уже сделали нереальное количество реализаций всего этого. Я сейчас буду говорить страшные слова для фронтэндов — Dockers farm, Kubernetes — это все так работает.

Самое приятное, что, во-первых, облачные функции остаются такими же простыми. Если у вас были функции на AWS или на лямбдах, перевести их в open source все так же просто.

Ниже перечислены далеко не все разработки. Я просто выбрала побольше и поинтереснее. Полный список огромный: очень много стартапов начинают сейчас работать на этой теме:

  • Iron functions
  • Fnproject
  • Openfaas
  • Apache OpenWhisk
  • Kubeless
  • Fission
  • Funktion

Я попробовала Fnproject и потратила всего пару часов, чтобы перевести это изоморфное приложение на Fnproject и запустить у себя локально с Kubernetes-контейнером.

Все так же быстро масштабируется. У вас будет связка API Gateway (конечно, без остальных сервисов), но у вас останется URL, который вызывает лямбду. И на самом деле почти все могут забыть о серверах, как и обещалось, кроме одного человека, который будет деплоить этот фреймворк и настроит эту оркестрацию Kubernetes, чтобы потом счастливые разработчики могли это использовать.

Минутка рекламы. Недавно мы анонсировали конференцию HolyJS 2018 Moscow, которая пройдет 24-25 ноября в Москве. На сайте уже есть первые спикеры и доклады, а также билеты по Early Bird-цене.

Автор: Евгений Трифонов

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js