Краткий экскурс в AWS Lambda


Что это?


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

Зачем ее использовать?


  • Деньги. Вы платите только за то время, когда сервис работает.
  • Скорость. Сама по себе лямбда поднимается и работает очень быстро.
  • Удобство. Лямбда имеет много возможностей по интеграции с сервисами AWS.
  • Производительность. Параллельно может выполняться, в зависимости от региона максимально от 1000 до 3000 экземпляров. И при желании, этот лимит можно поднять, написав в поддержку.

У этого подхода есть и свои минусы, вы не можете управлять операционной системой на который выполняется код, не можете контролировать ЦП, память и ресурсы. Всем этим занимается AWS.

Все что вы можете, это выбрать язык, из поддерживаемых AWS Lambda.

Что могёт?


Ниже представлен краткий перечень основных функций AWS Lambda. Далее все рассмотрим по порядку.



1. Triggers


Triggers — это «возбудители» лямбды. В некотором роде лямбду можно сравнить с PHP, в том плане, что для нас она выполняется и умирает. Далее мы подробно рассмотрим механизм работы. Пока нужно понимать что лямбда, это одна функция, которая выполняется по запросу из триггеров.

Ниже список всех возможных триггеров:

API Gateway
AWS IoT
Alexa Skills Kit
Alexa Smart Home
Application Load Balancer
CloudFront
CloudWatch Events
CloudWatch Logs
CodeCommit
Cognito Sync Trigger
DynamoDB
Kinesis
S3
SNS
SQS

Для каждого из них вам нужно будет настроить уникальные параметры, которые доступны для этих триггеров. Также вы можете настроить несколько триггеров на одну лямбду. От типа триггера зависит, будет лямбда выполняться синхронно или асинхронно.
Notice: Обратите внимание, что лямбду можно заставить выполниться, так и с помощью AWS CLI, AWS SDK в ручном режиме, передавая все необходимые параметры. В том числе будет она выполняться синхронно или нет

Давайте разберем на примере:


1. API Gateway — позволяет дергать лямбду по http запросу и требует вернуть результат пользователю. Такая операция не может выполняться асинхронно, т.к. требует ответа. Для синхронных операций некоторые функции недоступны.

2. SQS — к примеру, если наша лямбда обрабатывает сообщения от SQS, возвращать результат никуда не нужно и она может выполняться асинхронно. При асинхронном выполнении появляется несколько новых возможностей, к примеру, мы можем настроить повторное выполнение в случае ошибки, или отправлять такие запросы дальше в «мертвую» очередь SQS.

2. Permissions to AWS Services


Это сервисы AWS к которым лямбда имеет доступ по умолчанию. Что это значит? В функции которую вы будете писать всегда можно подключить AWS SDK и без ключей или каких либо параметров авторизации вы сможете использовать доступные сервисы. Все доступные сервисы вы определяете в IAM Role которую используете для этой лямбды.

Для каждого используемого языка есть своя SDK, которая умеет общаться с основными сервисами AWS.
Notice: для каждой лямбды вы настраиваете IAM Role от лица который будет запускаться лямбда

3. VPC


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

4. Online Editor


Также AWS Lambda предоставляет возможность редактировать код вашей функции напрямую с интерфейса в вашем браузере.



5. Logging


Все запросы на лямбду логируются в CloudWatch, туда же записываются данные по времени выполнения и памяти, эти данные могут очень помочь для установки лимитов. Также в коде есть возможность логировать собственные данные(к примеру в Node.js через console.log).

Дополнительно вы всегда можете увидеть статистику по использованию лямбды на вкладке Monitoring

6. Environment Variables


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

7. Code


Теперь самая интересная часть, сама по себе лямбда состоит из нескольких частей.

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

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

2. Function Environment — в коде должна обязательно находится функция, которая непосредственно будет выполняться при каждом запуске лямбды(Handler). О ней ниже. А перед ней находится ее окружение, которое мы задаем. Дело в том, что управление ресурсами происходит таким образом, что это окружение, хранится отдельно от функции какое-то время после ее завершения. И при следующем старте, возобновляется, не тратя на инициализацию время и ресурсы. Таким образом, все что возможно, нужно проинициализировать до самой функции, к примеру конфигурации, подключение библиотек и т.п.

3. Handler — непосредственно сам по себе выполняемый код, в зависимости от языка, определяется по разному. Для примера возьмем Node.Js. Для того что бы ваш код выполнился, нужно:

  1. js файл — 1шт
  2. exports.yourFunction = () => {//Ваш код} — 1шт

По умолчанию запускается index.js и ищет в нем функцию с именем «handler». Затем выполняет ее. Ваша функция может быть асинхронной в коде. На синхронное выполнение лямбды это не влияет.

Ниже пример кода, постараюсь описать что происходит там:

//AWS SDK уже встроен, его не нужно загружать отдeльно
var AWS = require('aws-sdk'); // только подключить
//Все что вам нужно, лучше подключать здесь
//Это пример с API Gateway. 
//Если проще, то это обычный http запрос
exports.handler = async(event, context) => {
//В event нам приходит вся инфа о запросе
//В context нам приходит текущий контекст aws lambda функции: 
// почему была запущена, кем и прочая вспомогательная инфа
   console.log('testing cloud watch'); 
   // ^ Таким образом мы можем писать в Cloud Watch кастомные сообщения
   return { 
       //Таким образом мы отвечаем на http запрос, думаю ниже все понятно
       statusCode: 200,
       body: 'Hello world',
       headers: {}
    };
};
exports.handler = (event, context, callback) => {
    //Это второй вариант с callback,
    //в каких-то случаях это может быть удобнее
   callback( 
        null, //<- Первый параметр, это если вам нужно вернуть ошибку  
        { // Второй параметр это успешно
            statusCode: 200,
            body: 'Hello world'
        }
    );
};

8. Версионирование


Сервис поддерживает удобное версионирование. Вкратце мы каждой загруженной копии можем выдавать версию. И добавлять алиасы, которые указывают на какую-то версию. Как это работает? Смотрите на схемку ниже



И так, теперь давайте разберемся что нужно сделать, чтобы получить то — что мы видим на диаграмме


Состояние первое


  1. Создать первую версию нашей лямбды. Вместе с первой версией у нас создается указатель на версию "$LATEST". Он всегда указывает на последнюю добавленную версию
  2. Добавить алиас «Dev». Тут мы выбираем куда привязать, у нас есть несколько вариантов — создать указатель на конкретный номер версии, в нашем случае «1», привязать указатель к "$LATEST", или привязать к другому алиасу. В данном случае мы прикрепляем к указателю "$LATEST", и теперь наш «Dev» алиас всегда будет указывать на последнюю ветку, так мы можем всегда на дев окружении тестировать наше приложение с последней версией лямбды. И если вдруг нам понадобится проверить, как оно работает на старой версии, нужно будет просто переключить в триггере алиас или изменить у алиаса ссылку на версию, не трогая наше приложение
  3. Добавить алиас «Stage» и привязать его к первой версии нашей лямбды
  4. Добавить алиас «Prod» и повторить, что мы делали для «Stage»

Notice: вот тут описано как работать с алиасами на практике. Практическая часть по lambda будет в следующей статье вместе с SQS

И так, сейчас мы получили что-то непонятное, по сути 3 алиаса ссылаются на одну версию, непонятно. Но ничего, все по порядку

Второе состояние


  1. Создать вторую версию нашей лямбды(Возможно добавить второй вывод «Hello world»). Тут хочу отметить, что в этот момент "$LATEST" будет смотреть сразу на вторую версию. И так как «Dev» привязан к "$LATEST", то он тоже будет смотреть на вторую версию.
  2. Далее, мы хотим чтобы наш «Stage» смотрел на вторую версию. Сейчас он привязан к версии «1». Тут нам нужно вручную поменять версию на которую указывает «Stage».
  3. Радуемся. Мы получили то — что видим как второе состояние на графике. То есть, наш «Prod» смотрит на первую версию, а «Dev» и «Stage» на вторую.

Третье состояние


Теперь, чтобы получить третье состояние, нам достаточно просто добавить еще пару строк в наш код и будет третья версия нашей лямбды. И «Dev» будет смотреть теперь на нее.

Резюмируем


И так, что мы имеем?

Маленькую. Быструю. Относительно дешевую. Автомасштабируемую. Версионируемую. Функцию.
В этой статье мы рассмотрели только теоретическую часть, знакомство с этим сервисом. Так же как и с SQS в прошлой статье. В следующей статье мы рассмотрим как эти два сервиса взаимодействуют друг с другом и в практической форме научимся их настраивать, использовать.

Комментарии (16)


  1. BlenderRU
    25.06.2019 12:47
    +2

    Использую Лямбду AWS как дополнение к хранилищу S3 там, где EC2 избыточен.
    В моем случае, например — для обработки загружаемых в S3 изображений, и создания нескольких изображений разных разрешений в соседнем S3 Bucket, которые потом подхватываются CDN'кой CloudFront.
    Для таких небольших операций — Лямбда шикарна, тем более, что с прошлого года появилась поддержка GoLang.


    1. vichenk Автор
      25.06.2019 12:48

      Да, спасибо, я действительно не добавил примеры. Так что, кто юзает лямбду активно, можете предлагать свои варианты


      1. Foreglance
        25.06.2019 19:13

        Lambda обычно используется как бэкенд для Lex чатботов, Alexa Skills, AWS IoT
        docs.aws.amazon.com/greengrass/latest/developerguide/config-lambda.html
        и может запускаться локально на Greengras Core:
        docs.aws.amazon.com/greengrass/latest/developerguide/lambda-functions.html


      1. random1st
        25.06.2019 21:52

        Вообще основной кейс использования Lambda — это добавление прослойки бизнес-логики в схему взаимодействия сервисов амазона. Например создание тасок на экспорт из Cloudwatch в S3, scheduler и т.п.


      1. tmin10
        26.06.2019 09:26

        Лямбду можно использовать как кастомный ресурс в cloudformation, тогда она сможет обрабатывать и менять параметры других создаваемых, обновляемых и удаляемых ресурсов в этом стеке (например, это нужно в связи с кривым API Cloudformation для Cognito Identity Pool).
        Кроме этого лямбду можно использовать для автоматизации различных операций в облаке через boto3 на питоне. Boto3 уже находится в поставке питона (хотя и не последней версии, возможно потребуется создать свой слой с последней версией boto3).
        Также можно слушать различные события и как-то на них реагировать (отправить сообщение в месседжер, что завершилась сборка в CodeBuild).


    1. random1st
      25.06.2019 21:48

      Насколько я помню сейчас для таких штук лучше юзать Lambda Edge в Cloudfront


  1. worldmind
    25.06.2019 18:19

    Стоит отметить, что если вам нужен постоянно запущенный демон, то лямбда не подойдёт, ибо имеет таймаут.


    1. vagon333
      25.06.2019 20:43

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

      Другое дело — работа в локальной сети.
      Некоторые организации достаточно закрыты и использование Cloud services противоречит корпоративной политике. В этом случае демон/сервис.


      1. worldmind
        26.06.2019 09:43

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


    1. tmin10
      26.06.2019 09:10

      Можно рекурсивно вызывать лямбду из лямбды, но перед тем, как так делать, стоит подумать — а надо ли оно.


  1. arheops
    26.06.2019 09:39

    Это все класно, но есть вещи о которых документация Amazon молчит.
    Например.

    Lambda функция настроенная на SQS ухитряется сделать МИЛЛИОН запросов на очередь вообще без нагрузки, за месяц

    Встроенный редактор практически не работает в Firefox.

    Функция может набросать в Cloudwatch логов на терабайт. Вы, естественно, об этом узнаете в конце месяца(ну и заодно узнаете о возможности warnings на использование от суппорта).

    Чтоб настроить простейшую функцию надо минут 30 потратить, даже знаючи(всякие roles/permissions и так далее).


    1. tangro
      26.06.2019 11:18

      30 минут надо потратить первый раз. Второй и дальше — по минуте. Как и с любой новой технологией.

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

      Встроенный редактор — задавная поделка для быстрого тестирования. Код лямбд (как и любой другой код) пишется в IDE, тестируется тестами, хранится в системе контроля версий и т.д.


      1. arheops
        26.06.2019 14:05

        Миллион запросов в очередь в месяц это был тестовый код от амазон в топике Lambda with SQS. Да, его оставили на месяц. Но блин, очередь то пустая была.
        Не знаю, может вам кажется, что пара минут. У меня только каждая форма в консоле 20-30 секунд грузится. Я вот как раз засек прошлый раз, ровно 30 минут настройка.


    1. tmin10
      26.06.2019 14:56

      У меня редактор работает в ФФ, но когда открываешь страничку, дефолный код не открывается, виснет на бесконечной загрузке. Но если закрыть файл и снова открыть его — всё нормально отображается.


      1. arheops
        26.06.2019 14:59

        Да, у всех так. Я ж и пишу «практически не работает». То работает то нет.
        Честно говоря, это не то, что ожидаешь от продуктов компании уровня Amazon.


        1. tmin10
          26.06.2019 15:06

          Оно очено стабильно и предсказуемо не работает :)
          У AWS так вроде всё хорошо снаружи, но чуть копнёшь глубже и всплывают недоработки, которые не фиксятся годами или бардак в документации. С этим просто приходится мириться и находить обходные пути.