Русский
Русский
English
Статистика
Реклама

Aws lambda

Перевод Реализуем бессерверный API с AWS Gateway и Lambda

01.04.2021 16:06:37 | Автор: admin


Без API не обходится ни одно веб-приложение. Для их разработки используются разные методы. Сейчас, например, набирает популярность бессерверный подход он экономичный, масштабируемый и относительно простой. Как ведущий провайдер бессерверных вычислений Amazon Web Services (AWS) вносит огромный вклад в бессерверную разработку. Здесь мы обсудим общие концепции реализации API с помощью AWS Lambda и других сервисов AWS.


Почему именно AWS Lambda?


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


Еще одно привлекательное преимущество оплата по мере использования. Вы платите только за общее время выполнения функций и не тратитесь в периоды простоя. Конечно, у Lambda, как и у любого другого сервиса, есть свои ограничения. Он не подходит для некоторых задач вроде очень длительных заданий, интенсивных вычислений или процессов, где мы должны контролировать среду выполнения. Но для реализации API сервис AWS Lambda обычно подходит идеально.


Роль API Gateway


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


HTTP API


API Gateway включает множество функций и интеграций. В какой-то момент в Amazon поняли, что разработчикам, которые используют бессерверные вычисления, обычно не нужно столько всего. Скорее, они предпочли бы в целом упростить процесс реализации. Наверное, поэтому в конце 2019 года AWS объявили о новых HTTP API, облегченной версии API Gateway, которая существенно упрощает разработку, повышает производительность и снижает расходы для бессерверных API. Несмотря на свою простоту, HTTP API поддерживают такие важные фичи, как настройка CORS для всех конечных точек, интеграция JWT, кастомные домены и соединения с VPC.


Принципы бессерверных API


Чтобы разобраться с главными принципами реализации бессерверных API, рассмотрим лаконичный пример простого приложения виртуальной доски, состоящий из двух конечных точек: POST для записи сообщений и GET для извлечения трех последних сообщений. Рассмотрим и другие возможные функции (параметры пути, CORS и авторизаторы), но постараемся не усложнять финальную реализацию.


AWS DynamoDB


Наш проект будет полностью бессерверным, поэтому используем AWS DynamoDB для хранения сообщений. Эта база данных отвечает принципам бессерверной архитектуры простота использования и оплата только за запросы. DynamoDB это база данных NoSQL ключ-значение от AWS, где данные хранятся на серверах AWS и полностью управляются Amazon.


AWS Serverless Application Model


Для реализации вам понадобится аккаунт AWS, а также установленный и настроенный фреймворк AWS Serverless Application Model (SAM). SAM это инструмент для создания, обновления и администрирования бессерверных приложений и всех ресурсов, которые нужны ему для работы. С AWS SAM мы не создаем каждый сервис вручную на веб-консоли мы просто описываем все, что нам нужно, в специальном файле шаблона.
После установки CLI переходим в нужный каталог и выполняем команду:


$ sam init -r nodejs12.x -n whiteboard
Инициализация нового проекта


Выбираем первую опцию и нажимаем Quick Start from Scratch (Быстрый запуск с нуля). Создается каталог нашей доски с минимумом установочных файлов.


Определяем необходимые ресурсы


Сначала открываем файл template.yml и удаляем все, что находится под разделом Resources. Прежде чем перейти к самому API, создаем дополнительные ресурсы. Определяем таблицу DynamoDB, где будут храниться сообщения:


Resources:  BoardMessagesTable:      Type: AWS::DynamoDB::Table      Properties:        TableName: board-messages-table        AttributeDefinitions:          - AttributeName: partKey            AttributeType: S          - AttributeName: createdAt            AttributeType: N        KeySchema:          - AttributeName: partKey            KeyType: HASH          - AttributeName: createdAt            KeyType: RANGE        ProvisionedThroughput:          ReadCapacityUnits: 5          WriteCapacityUnits: 5

Объявление таблицы DynamoDB


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


Теперь в том же файле, сразу под предыдущим определением, объявим HTTP API, с которым будут связаны все будущие конечные точки и функции.


BoardHttpApi:    Type: AWS::Serverless::HttpApi    Properties:      StageName: Test      CorsConfiguration: True

Объявление HTTP API


Это очень короткое и простое определение название этапа и конфигурация CORS, которые, впрочем, необязательны. Видите, каким простым и лаконичным может быть создание API? При необходимости, конечно, можно добавить самые разные свойства, например ссылку на функцию авторизации, определение домена, параметры логирования и другие.


Определяем функции обработчиков API


Наконец, определив все API, давайте объявим две функции, связанные с конкретными конечными точками.


PostMessageFunction:      Type: AWS::Serverless::Function      Properties:        Handler: src/handlers/postMessage.handler        Runtime: nodejs12.x        MemorySize: 128        Timeout: 5        Events:          PostMessage:            Type: HttpApi            Properties:              ApiId: !Ref BoardHttpApi              Method: POST              Path: /messages        Policies:          - AmazonDynamoDBFullAccess  GetMessagesFunction:      Type: AWS::Serverless::Function      Properties:        Handler: src/handlers/getMessages.handler        Runtime: nodejs12.x        MemorySize: 128        Timeout: 5        Events:          GetMessages:            Type: HttpApi            Properties:              ApiId: !Ref BoardHttpApi              Method: GET              Path: /messages        Policies:          - AmazonDynamoDBFullAccess

Объявление обработчиков для запросов POST и GET


Тут все понятно: две функции, одна из которых будет вызываться при запросе POST к пути /messages, а другая при запросе GET к тому же пути. У обеих функций есть ограничения на 128 МБ оперативки и пятисекундный таймаут. Код функций находится в файлах postMessage.js и getMessage.js в каталоге /src/handlers/. Создадим их прямо сейчас. (Мы предоставили полный доступ к DynamoDB в разделе Policies каждой функции, чтобы упросить код. В реальном проекте доступ нужно будет настроить более тонко).


Написание функций


Идем в каталог /src/handlers и создаем файлы со следующим содержимым:


postMessage.js


const AWS = require('aws-sdk');const dynamodb = new AWS.DynamoDB();exports.handler = async (event) => {  const { body } = event;  try {    const { author, text } = JSON.parse(body);    if (!author || !text) {      return {        statusCode: 403,        body: 'author and text are required!'      }    }    await dynamodb.putItem({      TableName: 'board-messages-table',      Item: {        msgId: { S: 'board' },        author: { S: author },        text: { S: text },        createdAt: { N: String(Date.now()) } // still expects string!      }    }).promise();    return {       statusCode: 200,       body: 'Message posted on board!',    }  } catch (err) {    return {       statusCode: 500,       body: 'Something went wrong :(',    }  }};

Код обработчика запросов POST


Эта функция будет выполняться в ответ на запросы POST. Она вычленяет из тела запроса автора и текст и сохраняет эти данные в базе данных. Еще она заполняет атрибут partKey одинаковым значением для всех записей. Обычно это не лучший метод, но для нашего примера подходит, потому что позволяет выполнять сортировку по ключам диапазона среди всех элементов с одинаковым ключом партиции. Кстати, DynamoDB всегда ожидает строку, даже если тип атрибута число.


getMessages.js


const AWS = require('aws-sdk');const dynamodb = new AWS.DynamoDB();exports.handler = async () => {  try {    const result = await dynamodb.query({      TableName: 'board-messages-table',      KeyConditionExpression: 'partKey = :partKey',      ScanIndexForward: false,      Limit: 3,      ExpressionAttributeValues: {':partKey': { S: 'board'}}    }).promise();    return {      statusCode: 200,      headers: {        'Content-Type': 'application/json',      },      body: JSON.stringify(result.Items),    }  } catch (err) {    console.log(err);    return {      statusCode: 500,      body: 'Something went wrong :(',    }  }};

Код обработчика запросов GET


В этой функции мы сначала получаем записи, у которых partKey равен board, потом задаем для ScanIndexForward значение false, чтобы последние сообщения отображались сверху, и наконец с помощью свойства Limit указываем, что хотим увидеть только три сообщения.


Развёртывание


Деплоить с AWS SAM легко достаточно одной команды с несколькими введенными значениями. Переходим в root-каталог проекта и выполняем команду:


$ sam deploy --guided

Команда развертывания


Нас попросят ввести имя приложения и выбрать регион AWS, а еще подтвердить несколько действий:



Указание и подтверждение параметров


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



Список создаваемых ресурсов их статусы


Когда процесс завершится, открываем веб-консоль AWS в браузере, переходим к сервису API, находим только что созданный API и копируем URL к корневому эндпоинту нашего API.



URL для конечной точки root API


Тестируем API


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


curl -d '{"author":"name", "text":"Message text"}' -H "Content-Type: application/json" -X POST https://your-api-id.execute-api.your-region.amazonaws.com/test/messages

Выполнение запроса POST в curl


Отправляем несколько запросов с разными сообщениями. Если все нормально, в консоли отобразится Message posted on board! (Сообщение опубликовано на доске) без ошибок.


Чтобы извлечь последнее сообщение, выполним простую команду, даже короче предыдущей:


curl https://your-api-id.execute-api.your-region.amazonaws.com/test/messages

Выполнение запроса GET в curl


Вот и все. Мы создали простой HTTP API с AWS Lambda и AWS SAM. Конечно, в реальном проекте нужно будет больше функций и конфигураций, но принцип будет тот же: определяем ресурсы, определяем конфигурации, пишем код и запускаем деплой.


Подключение мониторинга Thundra


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


Можно подключить мониторинг Thundra к только что созданным функциям Lambda (см. краткое руководство). После подключения Thundra вам нужно будет инструментировать функции Lambda postMessage и getMessages, чтобы просмотреть подробную информацию о каждом вызове и получить общую картину приложения.


Выбираем функции в списке, нажимаем сначала кнопку Instrument, а затем OK.



Подтверждение инструментирования функции Lambda


Пробуем сделать несколько запросов к API, возвращаемся на дашборд Thundra, нажимаем на имя функции и выбираем вызовы из списка. Здесь мы видим время, производительность, входные и выходные данные функции и т. д. Это очень полезно при отладке API в реальных проектах.



Сведения об одном вызове


Если вы используете бессерверные вычисления в сложных проектах с разными сервисами AWS или других вендоров, вам определенно пригодится функция Unique Tracing, которая существенно упрощает устранение неполадок и отладку приложения.


Стоит ли использовать HTTP API?


С помощью HTTP API с AWS Lambda можно создавать высокопроизводительные и экономичные API. Хоть это и облегченная версия API Gateway REST API, она обладает всем необходимым функционалом и покрывает 90% нужд разработчиков. HTTP API не поддерживают некоторые полезные функции, вроде кэширования, валидации схем и трансформации ответов.


Кэширование вам, скорее всего, не пригодится, потому что HTTP API работают гораздо быстрее старых REST API, а валидацию и трансформацию можно выполнять на уровне кода функции.
Если у ваших разработчиков нет других причин отказаться от HTTP API, можете с уверенностью их использовать. Обычно бессерверная транзакция начинается с вызова API, а отслеживать асинхронный поток событий не так-то просто. В таких ситуациях используйте комплексную функцию распределенного трейсинга в Thundra. Thundra предоставляет 250 тысяч запросов в месяц бесплатно вполне достаточно для маленьких проектов или стартапов.

Подробнее..

Перевод Развертывание приложения Symfony в AWS Lambda

11.06.2021 18:10:18 | Автор: admin

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

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

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

Наш сценарий использования

Предоставить доступ к API, созданному с помощью Symfony, который публикует сообщения в LinkedIn. Процесс разработки будет включать этапы от написания до развертывания кода.

Пишем код

В Symfony 5-й версии появился новый компонент под названием Notifier, который дает возможность отправлять уведомления через разные сервисы (Slack, Twitter, Twilio и др.).

В Symfony нет встроенной поддержки LinkedIn, поэтому несколько месяцев назад я создал поверх Notifier шлюз для публикации контента в этой социальной сети. Исходный код шлюза можно посмотреть по ссылке, его же мы будем использовать и в этой демонстрации.

Приступаем

$ symfony new --full aws-lambda-linkedin-notifier$ cd aws-lambda-linkedin-notifier$ composer require eniams/linkedin-notifier

Включаем шлюз (см. документацию)

<?php// config/bundles.phpreturn [// others bundles,Eniams\Notifier\LinkedIn\LinkedInNotifierBundle::class => ['all' => true]];// .envLINKEDIN_DSN=

Логика публикации контента

<?phpclass PostContentController{    /**     * @Route("/contents", name="post_content", methods="POST")     */    public function __invoke(NotifierInterface $notifier, Request $request)    {        if(null !== $message = (\json_decode($request->getContent(), true)['message'] ?? null)) {            $notifier->send(new Notification($message, ['chat/linkedin']));            return new JsonResponse('message posted with success', 201);        }        throw new BadRequestException('Missing "message" in body');    }}

Логика проста: мы предоставляем доступ к API через маршрут /contents, который принимает запрос POST с сообщением message в его теле.

В 11-й строке мы отправляем публикуемое сообщение в LinkedIn благодаря Symfony и шлюзу это делается очень просто!

Будучи профессиональными разработчиками, покроем этот код автотестами:

<?phpclass PostContentControllerTest extends WebTestCase    /**     * @dataProvider methodProvider     */    public function testANoPostRequestShouldReturnA405(string $method)    {        $client = static::createClient();        $client->request($method, '/contents');        self::assertEquals(405, $client->getResponse()->getStatusCode());    }    public function testAPostRequestWithoutAMessageInBodyShouldReturnA400()    {        $client = static::createClient();        $client->request('POST', '/contents');        self::assertEquals(400, $client->getResponse()->getStatusCode());    }    public function testAPostRequestWithAMessageInBodyShouldReturnA201()    {        $request = new Request([],[],[],[],[],[], json_encode(['message' => 'Hello World']));        $notifier = new class implements NotifierInterface {            public function send(Notification $notification, Recipient ...$recipients): void            {            }        };        $controller = new PostContentController();        $response = $controller->__invoke($notifier, $request);        self::assertEquals(201, $response->getStatusCode());    }    public function methodProvider()    {        return [            ['GET'],            ['PUT'],            ['DELETE'],        ];    }view rawTestPostContentController.php hosted with  by GitHub

Код готов! Пришло время его развернуть

Стоп! Что?! AWS Lambda не поддерживает PHP!

Именно так: AWS Lambda поддерживает не все языки программирования, а только некоторые, в том числе Go, Java, Python, Ruby, NodeJS и .NET.

Теперь надо учить новый язык и переписывать код? Надеюсь, нет!

Ничего переписывать не придется благодаря Матье Напполи (Matthieu Nappoli), создателю Bref.sh, и замечательной команде, помогающей ему поддерживать этот проект с открытым исходным кодом.

Bref позволяет развертывать PHP-приложения в AWS и запускать их на AWS Lambda.

Конфигурация развертывания

Добавим в kernel.php обработку логов:

<?php    // Kernel.php    public function getLogDir(): string    {        if (getenv('LAMBDA_TASK_ROOT') !== false) {            return '/tmp/log/';        }        return parent::getLogDir();    }    public function getCacheDir()    {        if (getenv('LAMBDA_TASK_ROOT') !== false) {            return '/tmp/cache/'.$this->environment;        }        return parent::getCacheDir();    }

Подготовим фреймворк Serverless (см. документацию):

$ npm install -g serverless$ serverless config credentials --provider aws --key  --secret$ composer require bref/bref

Зададим конфигурацию в файле serverless.yaml:

service: notifier-linkedin-apiprovider:    name: aws    region: eu-west-3    runtime: provided    environment: # env vars        APP_ENV: prod        LINKEDIN_DSN: YOUR_DSNplugins:    - ./vendor/bref/breffunctions:    website:        handler: public/index.php # bootstrap         layers:            - ${bref:layer.php-73-fpm} # https://bref.sh/docs/runtimes/index.html#usage         timeout: 28 # Timeout to stop the compute time        events:            - http: 'POST /contents' # Only POST to /contents are allowedpackage:    exclude:        - 'tests/**'view rawserverless.yaml hosted with  by GitHub

Развертываем!

$ serverless deployServerless: Packaging service...Serverless: Excluding development dependencies...Serverless: Uploading CloudFormation file to S3...Serverless: Uploading artifacts...Serverless: Uploading service notifier-linkedin-api.zip file to S3 (10.05 MB)...Serverless: Validating template...Serverless: Updating Stack...Serverless: Checking Stack update progress.......................Serverless: Stack update finished...Service Informationservice: notifier-linkedin-apistage: devregion: eu-west-3stack: notifier-linkedin-api-devresources: 15api keys:  Noneendpoints:  POST - https://xxx.execute-api.eu-west-3.amazonaws.com/dev/contentsfunctions:  website: notifier-linkedin-api-dev-websitelayers:  NoneServerless: Removing old service artifacts from S3...Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.

Теперь наш код развернут в AWS Lambda, а API доступен по адресу https://xxx.execute-api.eu-west-3.amazonaws.com/dev/contents.

Попробуем:


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

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru