Вступ
Безсерверні обчислення усувають необхідність керування інфраструктурою, дозволяючи розробникам зосередитися виключно на коді. AWS надає три основні безсерверні сервіси: AWS Lambda для обчислень на основі подій, Amazon API Gateway для створення API та AWS Step Functions для оркестрації розподілених робочих процесів.
Цей посібник досліджує шаблони безсерверної архітектури, моделі виконання Lambda, типи інтеграції API Gateway та стан-машини Step Functions. Ми розглянемо оптимізацію холодних стартів, стратегії кешування API та шаблони обробки помилок для production навантажень.
Серія AWS Developer Certification
📚 Переглянути повний посібник AWS Developer Certification - Опануйте всі 7 частин з нашим комплексним шляхом навчання.
Це Частина IV (Поточна стаття) нашого комплексного 7-частинного посібника для AWS розробників:
- Частина I: IAM EC2 та Auto Scaling
- Частина II: RDS Aurora та DynamoDB
- Частина III: SQS SNS та Kinesis
- Частина IV: Lambda API Gateway (Поточна стаття)
- Частина V: ECS Fargate та IaC
- Частина VI: Cognito KMS Security
- Частина VII: CodePipeline та Monitoring
← Частина III: SQS SNS та Kinesis | Частина V: ECS Fargate та IaC →
AWS Lambda
Модель виконання Lambda
Lambda виконує код у відповідь на події без підготовки серверів, з автоматичним масштабуванням та оплатою за використання.
Ключові специфікації:
- Пам'ять: 128 MB до 10 GB (CPU масштабується з пам'яттю)
- Таймаут: Максимум 15 хвилин
- Пакет розгортання: 50 MB (запакований), 250 MB (розпакований)
- Одночасність: 1,000 одночасних виконань на регіон (м'яке обмеження)
- Ціноутворення: $0.20 за 1M запитів + $0.0000166667 за GB-секунду
Приклад функції Lambda
Node.js Lambda з DynamoDB:
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
const {
DynamoDBDocumentClient,
GetCommand,
PutCommand,
} = require('@aws-sdk/lib-dynamodb');
// Ініціалізувати поза обробником (повторно використовується між викликами)
const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);
exports.handler = async event => {
const userId = event.pathParameters.id;
try {
// Отримати елемент з DynamoDB
const response = await docClient.send(
new GetCommand({
TableName: process.env.TABLE_NAME,
Key: { userId },
}),
);
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify(response.Item),
};
} catch (error) {
console.error('Помилка:', error);
return {
statusCode: 500,
body: JSON.stringify({ error: error.message }),
};
}
};
Виклик Lambda через AWS CLI:
# Синхронний виклик
aws lambda invoke \
--function-name my-function \
--payload '{"userId": "123"}' \
response.json
# Асинхронний виклик
aws lambda invoke \
--function-name my-function \
--invocation-type Event \
--payload '{"userId": "123"}' \
response.json
Типи викликів Lambda
- API Gateway, ALB, код застосунку
- Викликач чекає на відповідь
- Повторні спроби: Відповідальність клієнта
- S3, SNS, EventBridge, CloudWatch Events
- Lambda ставить в чергу внутрішньо, повертається негайно
- Повторні спроби: 2 автоматичні повторні спроби з експоненційною затримкою
- Налаштуйте DLQ (SQS/SNS) для невдалих подій
Event Source Mapping (Опитування):
- SQS, Kinesis, DynamoDB Streams
- Lambda опитує джерело та викликає функцію
- Пакетна обробка з налаштовуваним розміром пакета
Оптимізація холодних стартів
- Мінімізувати розмір пакета - Видалити невикористовувані залежності
- Збільшити пам'ять - Більше RAM = швидший CPU та мережа
- Утримувати функції теплими - Використовувати Provisioned Concurrency для критичних API
- Ініціалізувати поза обробником - Повторно використовувати з'єднання між викликами
- Використовувати ARM (Graviton2) - Зниження ціни на 20%, швидше на 19%
// ❌ Погано - ініціалізується при кожному виклику
exports.handler = async event => {
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
// ... решта коду
};
// ✅ Добре - повторно використовує з'єднання
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
exports.handler = async event => {
// Використовувати існуючий клієнт dynamodb
};
Amazon API Gateway
Архітектура API Gateway
API Gateway створює RESTful та WebSocket API з вбудованою авторизацією, кешуванням та throttling.
Типи API:
- REST API: Повний функціонал, кешування, власні домени
- HTTP API: Нижча вартість (дешевше на 70%), нижча затримка, простіший
- WebSocket API: Двостороння комунікація реального часу
Типи інтеграції API Gateway
Lambda Proxy Integration (AWS_PROXY):
- Запит проходить до Lambda як є
- Lambda має повертати специфічний формат відповіді
- Найпоширеніший шаблон
Lambda Custom Integration (AWS):
- Трансформація запиту/відповіді через VTL (Velocity Template Language)
- Більше контролю над mapping
HTTP Proxy Integration:
- Переадресація до HTTP endpoint
AWS Service Integration:
- Пряма інтеграція з DynamoDB, S3 тощо (Lambda не потрібен)
Тестування API Gateway з curl
# GET запит
curl https://api.example.com/users/123
# POST з JSON body
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
# З Authorization заголовком
curl https://api.example.com/users \
-H "Authorization: Bearer eyJhbGc..."
# З API Key
curl https://api.example.com/users \
-H "x-api-key: abc123xyz"
# Інвалідація кешу для конкретного запиту
curl https://api.example.com/users \
-H "Cache-Control: max-age=0"
API Gateway Authorizers
Приклад Lambda Authorizer:
exports.handler = async event => {
const token = event.authorizationToken; // З Authorization заголовка
const methodArn = event.methodArn;
// Перевірити токен (JWT, API key тощо)
const isValid = await validateToken(token);
if (isValid) {
return generatePolicy('user123', 'Allow', methodArn, {
userId: 'user123',
role: 'admin',
});
} else {
throw new Error('Unauthorized');
}
};
function generatePolicy(principalId, effect, resource, context = {}) {
return {
principalId,
policyDocument: {
Version: '2012-10-17',
Statement: [
{
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource,
},
],
},
context, // Доступно в Lambda через event.requestContext.authorizer
};
}
Кешування API Gateway
Увімкнути кешування на рівні stage:
- Розмір кешу: 0.5 GB до 237 GB
- TTL: 0 до 3600 секунд
- Налаштування кешу на рівні методу перевизначають налаштування stage
Параметри ключа кешу:
- Параметри query string
- Заголовки запиту
- Параметри шляху
Інвалідація кешу:
- Вручну через консоль/API
- Запит клієнта з заголовком
Cache-Control: max-age=0(потрібен дозвіл IAM)
AWS Step Functions
Стан-машина Step Functions
Step Functions оркеструє розподілені робочі процеси з візуальними стан-машинами та вбудованою обробкою помилок.
Типи станів:
- Task: Викликає Lambda, ECS, Batch або сервіс AWS
- Choice: Умовне розгалуження
- Parallel: Виконання гілок одночасно
- Wait: Затримка на тривалість або до timestamp
- Map: Ітерація по масиву
- Succeed/Fail: Термінальні стани
Приклад Step Functions
Визначення стан-машини:
{
"Comment": "Order processing workflow",
"StartAt": "ValidateOrder",
"States": {
"ValidateOrder": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:validate",
"Next": "ProcessPayment",
"Catch": [
{
"ErrorEquals": ["ValidationError"],
"Next": "OrderFailed"
}
],
"Retry": [
{
"ErrorEquals": ["States.TaskFailed"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2.0
}
]
},
"ProcessPayment": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:payment",
"Next": "UpdateInventory"
},
"UpdateInventory": {
"Type": "Task",
"Resource": "arn:aws:states:::dynamodb:updateItem",
"Parameters": {
"TableName": "inventory",
"Key": {
"product_id": { "S.$": "$.productId" }
},
"UpdateExpression": "SET stock = stock - :qty",
"ExpressionAttributeValues": {
":qty": { "N.$": "$.quantity" }
}
},
"Next": "OrderComplete"
},
"OrderComplete": {
"Type": "Succeed"
},
"OrderFailed": {
"Type": "Fail",
"Error": "OrderValidationFailed"
}
}
}
Запуск виконання з AWS SDK (Node.js):
const { SFNClient, StartExecutionCommand } = require('@aws-sdk/client-sfn');
const client = new SFNClient({});
async function startWorkflow(orderId, productId, quantity) {
const command = new StartExecutionCommand({
stateMachineArn:
'arn:aws:states:us-east-1:123456789012:stateMachine:order-processing',
input: JSON.stringify({
orderId,
productId,
quantity,
}),
});
const response = await client.send(command);
console.log('Execution ARN:', response.executionArn);
return response.executionArn;
}
Production найкращі практики
Найкращі практики Lambda
- Виділення пам'яті: Почніть з 512 MB, моніторте метрики CloudWatch, налаштовуйте (більше RAM = швидший CPU)
- Холодні старти: Використовуйте Provisioned Concurrency для API з чутливістю до затримок (коштує більше)
- Змінні середовища: Зберігайте конфігурацію, використовуйте AWS Systems Manager Parameter Store для секретів
- Таймаут: Встановіть відповідний таймаут (за замовчуванням 3с, максимум 15 хв)
- VPC: Тільки якщо доступ до приватних ресурсів (додає накладні витрати на холодний старт)
- Layers: Діліться залежностями між функціями (максимум 5 layers на функцію)
Найкращі практики API Gateway
- Кешування: Увімкніть для GET запитів зі стабільними даними (зменшує виклики Lambda)
- Throttling: Встановіть ліміти на рівні stage (за замовчуванням 10,000 запитів/сек)
- Валідація запитів: Використовуйте валідацію JSON схеми для відхилення неправильних запитів рано
- API Keys: Для контролю доступу партнерів/зовнішніх API (використовуйте Usage Plans)
- Власні домени: Використовуйте Route 53 + ACM для брендованих API
Найкращі практики Step Functions
- Обробка помилок: Завжди налаштовуйте блоки Retry та Catch
- Таймаути: Встановіть відповідні таймаути для кожного стану (запобігає зависанню виконань)
- Standard проти Express:
- Standard: Тривалі (максимум 1 рік), аудитовані, виконання рівно один раз
- Express: Високий об'єм, короткочасні (максимум 5 хв), принаймні один раз
- Оптимізація витрат: Використовуйте Express для високопропускних навантажень (дешевше на 60%)
Моніторинг та усунення неполадок
Ключові метрики:
Lambda:
Invocations- Кількість викликівErrors- Невдалі викликиDuration- Час виконанняThrottles- Запити, обмежені через ліміти одночасностіConcurrentExecutions- Кількість запущених інстансів
API Gateway:
Count- Загальна кількість API запитів4XXError/5XXError- Помилки клієнта/сервераLatency- Час обробки запитуCacheHitCount/CacheMissCount- Продуктивність кешу
Step Functions:
ExecutionsFailed- Невдалі виконанняExecutionTime- Тривалість робочого процесуExecutionThrottled- Обмежені виконання
Поради для іспиту
Ключові концепції:
- Таймаут Lambda максимум 15 хвилин (використовуйте Step Functions для довших робочих процесів)
- Lambda@Edge виконується в CloudFront edge locations (максимум 128 MB пам'яті, 5с таймаут)
- Кеш API Gateway розміри: 0.5 GB до 237 GB, TTL 0 до 3600с
- Step Functions Express максимум 5 хвилин, Standard максимум 1 рік
- Lambda Provisioned Concurrency утримує інстанси теплими (зменшує холодні старти)
Поширені сценарії:
- "Потрібно виконувати код 30 хвилин" → Step Functions + Lambda (ланцюгові функції)
- "Зменшити затримку API" → Кешування API Gateway + Provisioned Concurrency
- "Холодні старти Lambda" → Збільшити пам'ять, використовувати Provisioned Concurrency
- "Оркеструвати мікросервіси" → Step Functions
- "Двостороння комунікація реального часу" → API Gateway WebSocket
- "Обробити 10,000 елементів паралельно" → Step Functions Map стан
Висновок
Безсерверні сервіси AWS дозволяють створювати масштабовані застосунки без керування інфраструктурою. Lambda надає обчислення на основі подій з автоматичним масштабуванням, API Gateway створює безпечні API з вбудованими функціями, а Step Functions оркеструє складні робочі процеси з візуальними стан-машинами.
Обирайте Lambda для обробки на основі подій, API Gateway для RESTful та WebSocket API, та Step Functions для координації розподілених сервісів. Розуміння моделей виконання, шаблонів інтеграції та технік оптимізації є важливим як для production безсерверних архітектур, так і для іспиту AWS Certified Developer Associate.
Часті запитання
П: Як працюють Lambda cold starts та як їх мінімізувати?
Cold starts виникають, коли Lambda ініціалізує нове середовище виконання після простою або масштабування. Ініціалізація включає завантаження коду, запуск runtime та виконання коду ініціалізації. Мінімізуйте холодні старти, збільшуючи пам'ять (швидший CPU), використовуючи Provisioned Concurrency, зменшуючи розмір пакету, тримаючи функції теплими з EventBridge або оптимізуючи код ініціалізації.
П: Чим відрізняються API Gateway REST від HTTP API?
REST API надають повний набір функцій з авторизаторами запитів, перетворенням, WAF інтеграцією та планами використання. HTTP API оптимізовані для низької затримки та економічності (на 71% дешевше) з простішою конфігурацією. Використовуйте REST API для складних вимог, HTTP API для простих проксі з кращою продуктивністю.
П: Як працює Step Functions error handling?
Step Functions обробляє помилки за допомогою полів Retry та Catch в стані. Retry автоматично повторює відмовлені стани з експоненційним backoff. Catch перехоплює конкретні помилки та переходить до стану обробки помилок. Використовуйте States.ALL для всіх помилок, States.Timeout для таймаутів або конкретні типи помилок, як Lambda.ServiceException.
П: Що таке Lambda execution context reuse?
Lambda повторно використовує середовище виконання для наступних викликів для зменшення холодних стартів. Код поза обробником виконується один раз при холодному старті та повторно використовується. Використовуйте це для з'єднань з базою даних, SDK клієнтів або завантаження конфігурації. Завжди очікуйте холодних стартів; не залежте тільки від повторного використання контексту.
П: Як працює API Gateway throttling?
API Gateway обмежує на рівні акаунту (10,000 запитів/сек burst, 5,000 steady state) та на рівні стадії/методу. Обмеження використовує алгоритм token bucket. Перевищені запити отримують 429 Too Many Requests. Налаштуйте ліміти методу, використовуйте плани використання для клієнтів API або request integration throttling для захисту backend.
П: Що таке Step Functions Express vs Standard workflows?
Express workflows оптимізовані для великих обсягів подій (>100,000/сек) з максимумом 5 хвилин, синхронним або асинхронним виконанням, оплатою за виконання. Standard workflows для тривалих процесів (до 1 року), рівно-одне виконання, візуальне відстеження, оплата за переходи стану. Використовуйте Express для потоку IoT/подій, Standard для бізнес-процесів.
П: Як працює Lambda versioning та aliases?
Версії є незмінними знімками коду функції, конфігурації та залежностей з унікальним ARN ($LATEST змінюється). Aliases є вказівниками на версії з власними ARN і підтримкою зваженого трафіку. Використовуйте версії для аудиту, aliases для середовищ (prod/dev) та canary розгортань з розділенням трафіку 90/10 між версіями.