Особливості роботи з AWS Lambda та Serverless Framework

Півроку тому була розповідь про те, що таке serverless та AWS Lambda. А на початку осені, минулого року відгремів потужний InterLink Tech Talk, де також піднімалась тема амазонівських сервісів. І ось, нарешті, продовження. Цього разу мова піде про деякі особливості роботи з AWS Lambda та Serverless Framework. Розглянемо деякі наші помилки, що були допущені при роботі із serverless технологіями. Також буде трішки теорії стосовно того, як відбувається розгортання проекту, побудованого на основі AWS Lambda. Зазирнемо під капот Serverless Framework, так би мовити.

Переходячи до суті, давайте поміркуємо, що життєво необхідно для девелопера, крім кількох кружок кави на день, щоб ефективно працювати над розробкою проекту? Які функції повинна мати технологія для розробки, щоб девелоперу було комфортно з нею працювати? Як мінімум – це можливість запускати проект локально та дебажити його. Здавалося б, банальні та очевидні речі. Але serverless технології вміють здивувати.

Запустити локально проект на основі AWS Lambda, написаного на Node.js, можна за допомогою відповідного плагіна до Serverless Framework. Імітація роботи API Gateway на машині девелопера також підтримується. З використанням додаткових інструментів можливий і дебагінг. В даному випадку ніяких проблем не виникає. А от з іншими технологіями не все так просто. Напрклад, для Java немає такого плагіну. Тут допомогти може AWS Toolkit для Eclipse IDE. Для інших технологій (Python та C#) також необхідно шукати якісь сторонні інструменти.

Serverless Framework далеко не єдиний у своєму екземплярі. Інший представник цього виду – AWS SAM – має на озброєнні інструмент для локальної роботи з Node.js, Java та Python. Чи варто розглядати цей фреймворк або якийсь інший як альтернативу Serverless Framework – питання поки що відкрите. Між іншим, їх одночасне використання може бути цілком виправдане.

Написання тестів – також важливий етап будь-якого процесу розробки. Для комбінації Serverless Framework + Node.js, як водиться, є плагін для тестування лямбда-функцій. Для інших технологій, так само, – необхідно шукати альтернативи. Якщо не дуже важливо покривати тестами саме лямбда-функції, можна обмежитися модульними тестами лише для коду бізнес-логіки (вагомий аргумент на користь відокремлення коду для обробки викликів лямбда-функцій та бізнес-логіки).

Запустити локально DynamoDB, на щастя, не є проблемою і вирішується плагінами до Serverless Framework або окремими інструментами. Наприклад, Amazon надає завантажувану версію DynamoDB, яку можна інсталювати на девелоперській машині та працювати з нею як зі звичайною СКБД.

Крім AWS Lambla, DynamoDB та API Gateway існує ще безліч сервісів від Amazon, із якими, вірогідно, доведеться працювати. І ось тут починаються незручності. Для інших сервісів немає можливості локального запуску. Тому робота з ними ускладнюється необхідністю перевіряти все вживу, постійного розгортання проекту, вивчення логів тощо.

З початковими етапами розібралися, тепер найцікавіше – процес розробки serverless додатку.

Раніше вже згадувався такий сервіс, як CloudFormation. Перш ніж продовжити, пропоную трішки теорії, щоб детальніше розібратися, які функції надає цей сервіс та як він пов’язаний із Serverless Framework.

CloudFormation дозволяє розробникам та системним адміністраторам легко створювати та керувати групами пов’язаних ресурсів AWS. Ресурс – це те, що надають різні сервіси Amazon. Наприклад, лямбда функція є ресурсом, що надає сервіс AWS Lambda. API Gateway надає REST API та API методи. Таблиці – це ресурси DynamoDB. Навіть конфігурація логів для лямбда-функції також є ресурсом.

CloudFormation буквально є сервісом, що допомагає сформувати хмарину, або розгорнути serverless проект і може взаємодіяти практично з усіма відомими сервісами Amazon. Всі ресурси, які хочемо використовувати, з їх налаштуваннями та зв’язками, описуються у JSON або YML файлі – так званому темплейті. Темплейт – креслення нашого проекту, що дозволяє CloudFormation побудувати ту інфраструктуру, креслення якої ми надали. Для кожної властивості будь-якого ресурсу передбачено окремі властивості темплейта у відповідності до API сервіса. За допомогою команд CloudFormation API можна розгорнути serverless проект на основі сформованого темплейта.

Сам по-собі CloudFormation також надає ресурс – стек. Стек як раз і об’єднує ресурси, які вам потрібні, в одну невеличку хмарину. Всі ресурси в межах одного стеку можна вважати одним власноруч створеним сервісом.

Якщо коротко, то процес побудови стеку можна описати так:

  1. Створити темплейт
  2. Зберегти темлейт локально або на AWS S3
  3. Згодувати темплейт CloudFormation

Все ж, CloudFormation не всемогутній та має деякі недоліки. Дуже рідко, але трапляється, що деякі функції сервісів або властивості ресурсів не підтримуються CloudFormation. Це завдає деякі незручності, а саме унеможливлює їх програмне налаштування. Як результат – доводится шукати обхідні шляхи для реалізації якого-небудь функціоналу. Тому, вивчаючи якийсь сервіс Amazon, неохідно не забувати перевіряти можливості CloudFormation по відношенню до цього сервісу, якщо плануються його програмне налаштування.

Serverless Framework є універсальним інструментом, одне із завдань якого – спрощення процесу побудови CloudFormation темплейтів та роботи з ними. Розробник може оперувати певними аліасами для створення необхідних ресурсів. Так, декілька рядків конфігурації у serverless.yml файлі можуть перетворитися на кілька сотень рядків темплейту. Так само налаштування певних сервісів відбувається і для інших провайдерів хмарних обчислень (Microsoft Azure, IBM OpenWhisk, Google Cloud Platform та ін.), але з урахуванням їх особливостей та способів конфігурації.

Особливістю цього сервісу є обмежена кількість ресурсів, які можна помістити в один стек. Якщо конкретно, то кожен стек не може містити більше 200 ресурсів. Начебто не проблема, 200 – це не мало, для невеличкого проекту повинно вистачити. Але для нас, неочікувано, це стало проблемою. Ми швидко досягнули ліміту в 200 ресурсів, що призвело до переповнення нашого стеку.

Так ми збагнули основну помилку, яку допустили при проектуванні архітектури додатку. Наш API почав перетворюватися на невеличкий моноліт, хоча мав би проектуватися за принципом мікросервісної архітектури. Не даремно CloudFormation має таке обмеження. Він ніби недвозначно натякає на необхідність проектування мікросервісів.

Моноліт в розумінні AWS Lambda і, взагалі, світу serverless – поняття виключне. Кожна лямбда-функція і є тією мінімальною самостійною одиницею, яка може виконувати код незалежно від інших функцій. Але ми дійшли до того, що код деяких функцій був тісно пов’язаний. Хоча ззовні використовувалися лямбда-функції, всередині проект перетворювався на моноліт.

На додачу до цього всі наші лямбда-функції, таблиці та ін. ресурси лежали вперемішку в одній коробці під назвою CloudFormation стек.

Вирішити проблему лімітів CloudFormation можна декількома способами. Найскладніший – зламати проект та розбити його на мікросервіси (за одно позбутися монолітності). Можна зробити простіше: зекономити частину ресурсів (викинути логи, наприклад), переписати лямбда-функції так, щоб кожна обробляла декілька методів одного API ресурсу, замість створення лямбда-функцій окремо для кожного конкретного HTTP методу. І звісно ж, як ви вже, мабуть, здогадалися Serverless Framework має плагін і на такий випадок. Плагін групує ресурси по стеках за їх приналежністю до якогось сервісу: лямбда-функції окремо, API endpoints окремо, таблиці також окремо і т.д.

Ми обрали спосіб, який, на нашу думку, є найбільш правильним та, відповідно, найскладнішим. Нашому моноліту судилося розділитися на мікросервіси. Це, в свою чергу, передбачає розбиття одного великого стеку на декілька менших. Таке рішення породило ряд інших проблем.

По-перше, Serverless Framework не підтримує роботу з декількома стеками на основі однієї YML конфігурації. Тому для кожного мікросервіса необхідно було створити окрему конфігурацію. По суті, ми отримали декілька маленьких проектів в межах одного великого, що, в принципі, дуже схоже на типову реалізацію мікросервісів.

По-друге, створення відокремленої директорії, яка повинна містити спільні для всіх сервісів шматки коду. Serverless Framework дозволяє конфігурувати, які файли та директорії будуть автоматично завантажені до хмари разом із кодом додатку. Але під час розробки необхідно самостійно слідкувати за тим, щоб всі необхідні файли були в зоні видимості для коду мікросервіса.

По-трете, спільні для деяких частин додатку AWS ресурси. Найпростішим рішенням в даному випадку було створення окремого стеку для кожного такого ресурсу. Кожен стек може мати набір “виходів” (outputs) для зв’язування між собою ресурсів з різних стеків. На кількість виходів, між іншим, також є обмеження. А якщо буди чесним, то обмеження є абсолютно на все.

І, нарешті, останнє – необхідність у єдиному API endpoint для всіх мікросервісів. Так склалось, що ми вирішили іти саме таким шляхом. Так як ми маємо окремі мікросервіси, кожен має свій власний REST API та API endpoint. Налаштування єдиної точки входу було організовано через HTTP Proxy Integration – механізм, що надає API Gateway.

Так ми досягли того, що наш проект став більше нагадувати щось подібне до групи мікросервісів. Проект став більш структурованим, його легше розширювати. Час деплою одного невеликого сервісу менший, ніж час деплою моноліту, що зменшує кількість витрачених нервів під час деплою. З кожним новим функціоналом тепер необхідно додати ще один сервіс, замість того, щоб городити все в одну купу.

Структура папок проекту також зазнала змін. Кожному сервісу виділена його власна директорія з YML конфігурацією.

 

На цьому наші пригоди із Serverless Framework не закінчуються. Serverless технології стрімко розвиваються, аналогічно як і інструменти для роботи з ними. Вимоги бізнесу постають все біль цікаві, і нерідко вимогою є використання саме serverless. І не дивно, судячи з величезних можливостей, які надають хмарні обчислення.

Serverless технології лише здаються кусючими. А без своїх цікавостей не обходиться жодна технологія. Тож давайте разом будувати світ мікросервісів із serverless!

Post A Reply