В этой статье мы обсудим, что такое бессерверное программирование и как начать работу с AWS Lambda в качестве разработчика Node.js.

С момента запуска AWS Lambda в 2014 году бессерверные (или FaaS - функция как услуга) вычисления становились все более популярными. Это позволяет вам сосредоточиться на функциональности ваших приложений, не беспокоясь о своей инфраструктуре.

В последние годы большинство облачных провайдеров начали предлагать свои собственные бессерверные версии: Microsoft запустила Функции Azure, а Google - Облачные функции. IBM выпустила бессерверную версию с открытым исходным кодом под названием OpenWhisk.

Бессерверные вычисления

Бессерверная архитектура - это разновидность событийной архитектуры - функции реагируют на определенные типы триггерных событий. Говоря об AWS, это может быть событие, инициированное S3, SNS или API-шлюзом, и это лишь некоторые из них.

События жизненного цикла функций AWS Lambda

Функции AWS Lambda выполняются в изолированной среде, как и контейнеры. Эта среда предоставляется с ресурсами, указанными в конфигурации функций (например, размер памяти).

AWS Lambda по-разному обрабатывает то, что происходит при первом вызове функции Lambda и последующих вызовах одной и той же функции Lambda.

Первый вызов новой лямбда-функции

Когда вы развертываете свою лямбда-функцию (или обновляете существующую), для нее будет создан новый контейнер.

Ваш код будет перемещен в контейнер, а код инициализации будет запущен до того, как первый запрос поступит в открытую функцию-обработчик.

Лямбда-функцию можно выполнить одним из следующих способов:

  • тайм-аут - время ожидания, указанное пользователем, истекло (на данный момент по умолчанию 5 секунд),
  • контролируемое завершение - вызывается обратный вызов функции-обработчика,
  • завершение по умолчанию - если все обратные вызовы завершили выполнение (даже без обратного вызова функции-обработчика),
  • сбой процесса.

Последовательные вызовы существующей лямбда-функции

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

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

Создание вашей первой функции

Теперь, когда мы закончили обсуждение событий жизненного цикла лямбда-функций, пришло время взглянуть на некоторые фактические реализации лямбда-функций!

Анатомия функции AWS Lambda (в Node.js)

/* Initialization part starts here */
const mysql = require('mysql')
const connection = mysql.createConnection({
  host : process.env.MYSQL_HOST, 
  user : process.env.MYSQL_USER, 
  password : process.env.MYSQL_PASSWORD, 
  database : process.env.MYSQL_DB 
})
/* Initialization part ends here */ 
/* Handler function starts here */
exports.handler = (event, context, callback) => { 
  const sql = 'SELECT * FROM users WHERE id = ' +
connection.escape(event.userId) 
  connection.query(sql, function (error, results, fields) { 
    if (error) { 
      return callback(error) 
    } callback(null, results) 
  }) 
} 
/* Handler function ends here */

Давайте посмотрим, что вы видите в приведенном выше примере:

  • инициализация - это часть фрагмента кода, которая запускается только один раз при создании контейнера. Это хорошее место для создания подключений к базе данных.
  • функция-обработчик - эта функция будет вызываться каждый раз при выполнении вашей лямбда-функции.
  • событие - эта переменная используется Lambda для передачи данных события в обработчик (например, HTTP-запрос).
  • контекст - переменная context используется для передачи информации времени выполнения для лямбда-функции, например, сколько времени осталось до завершения функции.
  • обратный вызов - с его помощью вы можете явно возвращать данные вызывающей стороне (например, HTTP-ответ).

Развертывание функций AWS

Поскольку теперь у нас есть работающая функция Lambda, пора ее развернуть.

Вот где начинаются ваши проблемы! Но почему?

По умолчанию, чтобы AWS Lambda работала, например, с HTTP, вам нужно управлять не только функцией AWS Lambda, но и шлюзом API.

Развертывание обычно означает загрузку ZIP-файла, который заменяет старую версию функции AWS Lambda. Чтобы избавить вас от головной боли, давайте познакомимся с бессерверной структурой.

Войдите в бессерверную структуру

Бессерверная структура - это решение с открытым исходным кодом под лицензией MIT, которое помогает легче создавать и управлять функциями AWS Lambda.

Serverless помогает создавать и настраивать все необходимые ресурсы для беспрепятственного запуска функций Lambda.

Чтобы начать работу с бессерверным режимом на AWS Lambda, достаточно всего нескольких команд:

# 1. Create a new Serverless project: 
$ serverless create --template aws-nodejs --path my-service 
# 2. Change into the newly created directory 
$ cd my-service 
# 3. Install npm dependencies 
$ npm install 
# 4. Deploy 
$ serverless deploy

Эти шаги создадут serverless.yml в вашем проекте, в котором будет храниться описание службы (например, сопоставление маршрутов для функций), а также каталог .serverless, содержащий файлы CloudFormation и развернутый артефакт ZIP.

Недостатки использования AWS Lambda

• Контроль поставщиков / блокировка

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

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

• Мульти аренды

Мультиарендность относится к ситуации, когда несколько клиентов работают на одном хосте. Это может вызвать проблемы как с точки зрения безопасности, так и с точки зрения надежности и производительности (например, при высокой нагрузке клиент замедляет работу другого).

Преимущества использования AWS Lambda

• Снижение эксплуатационных расходов.

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

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

• Сниженная стоимость масштабирования.

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

Представьте себе сценарий, когда вы еженедельно отправляете маркетинговые / коммерческие электронные письма, при этом пиковый трафик ваших сайтов будет присутствовать в следующие часы только после их отправки.

• Более простое оперативное управление.

Поскольку логика автоматического масштабирования вашей инфраструктуры обрабатывается поставщиком, вам даже не нужно думать о горизонтальном масштабировании вашего приложения - вам просто нужно написать его таким образом, чтобы его можно было масштабировать по горизонтали.

Подробнее

Надеюсь, после прочтения этой статьи вам стало интереснее, что Serverless и AWS Lambda могут для вас сделать. В таком случае я рекомендую изучить следующие дополнительные ресурсы:

Если у вас есть вопросы, дайте мне знать в комментариях ниже!

Первоначально опубликовано на blog.risingstack.com 23 мая 2017 г.