Проекти, де Lambda смикає Lambda напряму через SDK — це зв'язаність, крихкість і складність відлагодження. Коли з'являється п'ятнадцятий споживач тієї самої події, доводиться оновлювати кожне джерело. Event-Driven архітектура на серверлес вирішує це: компоненти спілкуються через події, а не прямі виклики. Lambda функція не знає, хто ще підписаний на результат її роботи. Це забезпечує слабку зв'язність, незалежне масштабування та можливість додавати нових споживачів без зміни джерела. Наш досвід у десятках проектів підтверджує: такий підхід у 3-5 разів прискорює впровадження нових сервісів порівняно з монолітним зв'язуванням, а вартість інфраструктури знижується на 30-50% за рахунок відмови від невикористовуваних ресурсів.
Чому Event-Driven, а не пряме зв'язування?
Прямі виклики Lambda з Lambda (через SDK Invoke) створюють жорсткі залежності. Якщо процес оплати смикає сервіс доставки, а через місяць потрібен фрод-фільтр, доводиться правити код оплати. В event-driven моделі кожен сервіс публікує події, а нові споживачі підписуються без змін джерела. Це радикально спрощує еволюцію системи та дозволяє незалежно деплоїти компоненти.
За даними AWS, EventBridge обробляє понад 4 трлн подій на місяць, забезпечуючи затримку менше 100 мс.
Порівняйте: при прямих викликах відмова однієї ланки руйнує весь ланцюг. EventBridge з SQS дає гарантію доставки та автоматичні ретраї — в 10 разів надійніше, ніж ручна обробка помилок.
Архітектура на прикладі e-commerce
Обробка замовлення без event-driven: PlaceOrder → ValidateInventory → ProcessPayment → SendEmail → UpdateAnalytics — все послідовно, тісно пов'язано.
З event-driven:
[Client] → PlaceOrder Lambda
↓
EventBridge: order.created
/ | \
ValidateInv SendEmail Analytics
↓
EventBridge: inventory.reserved
↓
ProcessPayment
↓
EventBridge: payment.processed
/ \
FulfillOrder SendReceipt
Кожен сервіс реагує на події незалежно. Новий сервіс (наприклад, fraud detection) підписується на order.created без змін існуючого коду.
Як це працює на практиці
AWS EventBridge: реалізація
# Custom event bus + rule + target
resource "aws_cloudwatch_event_bus" "orders" {
name = "orders-bus"
}
resource "aws_cloudwatch_event_rule" "order_created" {
name = "order-created"
event_bus_name = aws_cloudwatch_event_bus.orders.name
event_pattern = jsonencode({
"detail-type": ["OrderCreated"],
"source": ["com.company.orders"]
})
}
resource "aws_cloudwatch_event_target" "process_inventory" {
rule = aws_cloudwatch_event_rule.order_created.name
event_bus_name = aws_cloudwatch_event_bus.orders.name
arn = aws_lambda_function.validate_inventory.arn
}
Публікація події з Lambda:
import boto3
import json
from datetime import datetime
events = boto3.client('events')
def publish_order_created(order: dict):
events.put_events(
Entries=[{
'EventBusName': 'orders-bus',
'Source': 'com.company.orders',
'DetailType': 'OrderCreated',
'Detail': json.dumps({
'orderId': order['id'],
'customerId': order['customer_id'],
'items': order['items'],
'totalAmount': order['total'],
'timestamp': datetime.utcnow().isoformat()
}),
'Time': datetime.utcnow()
}]
)
SQS для надійної доставки
EventBridge + SQS = відмовостійка доставка з retry та dead letter queue. Використовуємо Terraform для інфраструктури як коду:
resource "aws_sqs_queue" "inventory_updates" {
name = "inventory-updates"
visibility_timeout_seconds = 300
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.inventory_dlq.arn
maxReceiveCount = 3 # After 3 failures → DLQ
})
}
resource "aws_lambda_event_source_mapping" "inventory_processor" {
event_source_arn = aws_sqs_queue.inventory_updates.arn
function_name = aws_lambda_function.process_inventory.arn
batch_size = 10
function_response_types = ["ReportBatchItemFailures"]
}
ReportBatchItemFailures — тільки невдалі повідомлення повертаються до черги, успішні не повторюються.
Обробник з partial failure
def handler(event, context):
failed_message_ids = []
for record in event['Records']:
try:
process_message(json.loads(record['body']))
except Exception as e:
# Тільки цей record піде в retry, інші — ОК
failed_message_ids.append({'itemIdentifier': record['messageId']})
return {'batchItemFailures': failed_message_ids}
Як забезпечити ідемпотентність?
В event-driven системах події можуть доставлятися двічі (at-least-once delivery). Кожен обробник повинен бути ідемпотентним. Використовуємо DynamoDB як таблицю обробки з ConditionExpression:
import boto3
dynamodb = boto3.resource('dynamodb')
processed_events = dynamodb.Table('processed_events')
def handler(event, context):
for record in event['Records']:
event_id = record['messageId']
# Перевірити, чи не оброблена подія вже
try:
processed_events.put_item(
Item={'event_id': event_id, 'ttl': int(time.time()) + 86400},
ConditionExpression='attribute_not_exists(event_id)'
)
except processed_events.meta.client.exceptions.ConditionalCheckFailedException:
continue # Already processed
process_event(record)
Процес впровадження
Впровадження event-driven архітектури під ключ включає етапи:
| Етап | Терміни |
|---|---|
| Проектування event schema + шини | 2–3 дні |
| EventBridge налаштування + правила маршрутизації | 2–3 дні |
| SQS + DLQ + Lambda event sources | 2–3 дні |
| Ідемпотентність обробників | 2–4 дні |
| Distributed tracing + моніторинг | 2–3 дні |
| Інтеграційне тестування | 2–4 дні |
Всі етапи можуть виконуватися паралельно для різних компонентів. Терміни залежать від складності бізнес-логіки та кількості сервісів. Середній проект — 14 робочих днів.
Порівняння: event-driven vs мікросервіси на REST
Таблиця порівняння
| Параметр | Event-Driven (AWS) | REST Мікросервіси |
|---|---|---|
| Зв'язність | Слабка (через події) | Сильна (прямі виклики) |
| Відмовостійкість | Вбудовані ретраї, DLQ | Ручна обробка, circuit breaker |
| Масштабування | Незалежне, per consumer | Вимагає синхронізації |
| Додавання нового сервісу | Підписка без змін | Часто правка API gateway |
| Затримка | ~100 мс (EventBridge) | ~10 мс (прямий виклик) |
Моніторинг event-driven системи
Ключові метрики:
- Event lag (SQS
ApproximateAgeOfOldestMessage) — наскільки свіжі події обробляються - DLQ depth — число подій у dead letter queue (ненульове значення = проблема)
- Processing rate vs production rate — чи встигає система споживати події
- End-to-end latency — час від події до результату через весь ланцюг
Ми налаштовуємо CloudWatch alarms та дашборди, щоб вчасно реагувати на відхилення. Досвід показує: гарний моніторинг скорочує час реакції на інциденти в 2-3 рази.
Скільки часу займає впровадження?
Терміни варіюються від 10 до 25 робочих днів залежно від кількості сервісів та складності бізнес-логіки. Оцінка проекту безкоштовна — пишіть, ми підготуємо детальний план та архітектурну схему.
Що входить у роботу
Документація архітектури та event schema, код Lambda-функцій та інфраструктура як код (Terraform), налаштування шин та черг, реалізація ідемпотентності, моніторинг та алерти, тестові скрипти, навчання команди. Ми даємо гарантію на працездатність рішення протягом місяця після деплою.
Замовте впровадження event-driven архітектури — ваша система стане гнучкішою та масштабованішою. Зв'яжіться з нами для оцінки вашого проекту, і ми підберемо оптимальне рішення.







