Списком
Розгортання системи в хмарі — це лише початок. Дійсна зрілість хмарних операцій визначається здатністю команди зрозуміти, що відбувається всередині системи в будь-який момент часу та швидко реагувати на відхилення від норми. Саме тут концепція спостережуваності (Observability) стає центральною.
Паралельно, будь-яка система врешті-решт зазнає збоїв — питання не «чи відбудеться відмова», а «коли» і «наскільки добре система відновиться». Проєктування систем з урахуванням відмов (Design for Failure) є фундаментальним принципом хмарної архітектури.
Monitoring (Моніторинг) — відповідає на питання «Чи справна система?». Ми заздалегідь знаємо, що перевіряти.
Observability (Спостережуваність) — відповідає на питання «Чому система поводить себе саме так?». Дозволяє досліджувати невідомі раніше стани.
Система є спостережуваною, якщо її внутрішній стан можна визначити лише на основі зовнішніх виходів (телеметрії).
Metrics (Метрики) — числові значення, що вимірюються у часі:
Метрики — агреговані, займають мало місця, ідеальні для алертів і дашбордів.
Logs (Журнали) — дискретні події у часі зі структурованим або неструктурованим текстом:
{
"timestamp": "2024-01-15T14:23:45.123Z",
"level": "ERROR",
"service": "payment-service",
"message": "Payment gateway timeout",
"transaction_id": "tx-9f8b2c",
"user_id": "u-12345",
"duration_ms": 5001,
"gateway": "stripe"
}
Логи детальні, але займають багато місця. Ідеальні для дебагінгу та розслідування інцидентів.
Traces (Розподілені трейси) — фіксація шляху запиту через усі мікросервіси системи:
HTTP GET /api/orders/123
│
├── auth-service (25ms) — перевірка токена
│
├── order-service (180ms) — обробка
│ ├── db-query (45ms) — SELECT * FROM orders
│ └── inventory-service (120ms) — перевірка наявності
│ └── db-query (35ms)
│
└── notification-service (15ms) — надсилання email
Трейси є критичними для мікросервісних архітектур — дозволяють знайти “вузькі місця” у ланцюжку запитів.
SLI (Service Level Indicator) — конкретна метрика, що вимірює якість обслуговування:
успішні запити / всі запити × 100%% запитів, що виконані швидше порогового часупомилкові запити / всі запитиSLO (Service Level Objective) — цільове значення SLI:
SLA (Service Level Agreement) — юридично обов’язкова угода між провайдером і клієнтом, базується на SLO. Передбачає компенсацію при порушенні.
Error Budget (Бюджет помилок):
SLO: 99.9% доступність / місяць
Error budget: 100% - 99.9% = 0.1% = 43.8 хвилин простою/місяць
Використано: 25 хвилин → залишок: 18.8 хвилин
Команда може витрачати error budget на ризиковані деплойменти. Якщо budget вичерпано — нові feature-деплойменти призупиняються до кінця місяця.
Amazon CloudWatch — центральна платформа моніторингу та спостережуваності в AWS.
Компоненти CloudWatch:
CloudWatch Metrics:
CloudWatch Alarms (Сповіщення):
Alarm: WebServerCPUHigh
Metric: CPUUtilization (EC2 Auto Scaling Group)
Threshold: > 80% протягом 3 з 3 хвилин
Action: → SNS notification (email/SMS)
→ Auto Scaling: додати 2 інстанси
CloudWatch Dashboards: Кастомні дашборди для візуалізації метрик у реальному часі. Підтримку: графіки, числа, heatmap, alarm status.
CloudWatch Logs:
CloudWatch Container Insights: Автоматичний збір метрик та логів з EKS та ECS кластерів.
Агент CloudWatch (CloudWatch Agent): Встановлюється на EC2 для збору додаткових метрик (використання RAM, дискового простору — не доступні за замовчуванням) та надсилання логів застосунків.
CloudWatch Synthetics (Canary):
Azure Monitor — єдина платформа моніторингу в Azure:
Azure Application Insights (APM):
Google Cloud Monitoring:
Google Cloud Trace: розподілене трасування запитів (автоматична інтеграція з App Engine, GKE).
Google Cloud Profiler: аналіз продуктивності коду в production (CPU, heap, mutex) без значного впливу на затримку.
| Інструмент | Тип | Особливості |
|---|---|---|
| Prometheus + Grafana | Open-source | Стандарт для K8s-моніторингу |
| Datadog | SaaS | Повна observability, AI-аналітика |
| New Relic | SaaS | APM + Infrastructure + Logs в одному |
| Dynatrace | SaaS | AI-автоматична побудова топології |
| Elastic (ELK) | Open-source + SaaS | Потужний пошук та аналіз логів |
Структуроване логування (JSON):
{
"timestamp": "2024-01-15T14:23:45.123Z",
"level": "INFO",
"service": "order-service",
"version": "1.4.2",
"trace_id": "abc123def456",
"span_id": "xyz789",
"user_id": "u-12345",
"action": "order_created",
"order_id": "ord-98765",
"amount": 149.99,
"currency": "UAH"
}
Переваги структурованих логів:
Рівні логування:
Elasticsearch + Logstash + Kibana (ELK) — класичний стек для обробки Journal:
Джерела логів Збір/Обробка Зберігання Візуалізація
─────────────── ───────────── ────────── ────────────
EC2 Instance ──► Filebeat ──► ──► Elasticsearch ──► Kibana
Lambda ──► Fluentd ──► Logstash ─────► (індекс) (дашборд,
ECS ──► Logstash ──► ──► Alerts)
K8s Pods ──► Fluent Bit► ──►
OpenSearch — AWS-форк Elasticsearch, що використовується в Amazon OpenSearch Service (замінник Elasticsearch у хмарі AWS).
Retention Policy (Термін зберігання):
Log Sanitization (Приховування PII):
# Неправильно — логування картки
logger.info(f"Processing card {card_number}") # '4532-1234-5678-9012'
# Правильно — маскування
logger.info(f"Processing card ****{card_number[-4:]}") # '****9012'
У мікросервісній архітектурі один HTTP-запит може пройти через 10–20 сервісів. Розподілене трасування відстежує весь шлях запиту та вимірює час виконання на кожному кроці.
Terminology:
X-Trace-Id)AWS X-Ray — сервіс розподіленого трасування AWS:
Service Map (X-Ray Console):
[Browser] ──► [API Gateway] ──► [Lambda: orders] ──► [DynamoDB]
│
└──► [Lambda: inventory] ──► [SQS]
│
└──► [SES: email]
Для кожного вузла X-Ray показує:
X-Ray Segment та Subsegment:
from aws_xray_sdk.core import xray_recorder
@xray_recorder.capture('process_order')
def process_order(order_id):
with xray_recorder.in_subsegment('validate'):
validate_order(order_id)
with xray_recorder.in_subsegment('db_write'):
save_to_db(order_id)
OpenTelemetry (OTel) — відкритий стандарт та набір SDK для збору метрик, логів і трейсів, що підтримується CNCF.
Переваги OTel:
Принцип «Everything can fail» стверджує: будь-який компонент системи врешті-решт відмовить. Задача архітектора — спроєктувати систему так, щоб відмова одного компонента не призводила до відмови всієї системи.
Chaos Engineering (Хаос-інженерія): Навмисне введення збоїв у production-систему для перевірки її стійкості.
Circuit Breaker (Автоматичний вимикач): Патерн, що запобігає каскадним відмовам при недоступності залежності.
Стан: CLOSED (нормальний)
→ сервіс B недоступний: помилки
→ поріг помилок перевищено
Стан: OPEN (відкритий)
→ запити до B відхиляються миттєво (fallback)
→ чекаємо час відновлення (30 сек)
Стан: HALF-OPEN
→ пробний запит до B
→ успіх → CLOSED
→ невдача → OPEN знову
Retry з Exponential Backoff та Jitter:
import random
import time
def call_with_retry(func, max_retries=3):
for attempt in range(max_retries):
try:
return func()
except TransientError as e:
if attempt == max_retries - 1:
raise
# Exponential backoff + random jitter
wait = (2 ** attempt) + random.uniform(0, 1) # 1s, 2s, 4s + jitter
time.sleep(wait)
Без jitter: всі клієнти після першої відмови звертаються одночасно → “thundering herd” → сервер перевантажується → нові відмови.
Bulkhead (Водонепроникна перегородка): Ізоляція ресурсів між незалежними частинами системи. Навіть якщо один сервіс вичерпає thread pool — інші продовжать роботу.
Worker Threads Pool: 100 потоків
├── /api/orders: 40 потоків (ізольований пул)
├── /api/users: 30 потоків (ізольований пул)
└── /api/payments: 30 потоків (ізольований пул)
Timeout (Таймаут): Завжди встановлюйте таймаут для зовнішніх викликів. Без таймауту — один повільний зовнішній сервіс може блокувати всі потоки застосунку.
# Без таймауту — небезпечно!
response = requests.get("http://slow-service.internal/api")
# З таймаутом — правильно
response = requests.get("http://slow-service.internal/api", timeout=(3, 10))
# (3s — connect timeout, 10s — read timeout)
Cache-Aside (Кешування): Читання з кешу (Redis, Memcached) перед зверненням до БД знижує навантаження на БД та покращує відмовостійкість при пікових навантаженнях.
Graceful Degradation (Поступова деградація): При відмові залежного сервісу — повертати спрощений варіант відповіді замість помилки:
Multi-AZ (всередині регіону):
Multi-Region (між регіонами):
Runbook (Інструкція з реагування) — задокументована покрокова інструкція для реагування на конкретний тип інциденту. Критично важлива для ефективного відновлення в 3 годині ночі:
Incident: High Error Rate on Payment Service (> 5%)
Severity: P1
1. Перевірити CloudWatch Dashboard: payment-service-prod
2. Перевірити останні деплойменти (CodeDeploy Console, останні 2 год)
3. Перевірити залежності: Stripe API Status (https://status.stripe.com)
4. Перевірити логи: CloudWatch Insights → payment-service → рівень ERROR
5. Якщо деплоймент — виконати rollback (AWS CodeDeploy → попередня версія)
6. Якщо Stripe → увімкнути резервний провайдер (PayPal) через feature flag
7. Повідомити stakeholders через Slack #incidents
8. Провести Post-Mortem протягом 48 годин
Post-Mortem (Пост-метрем): Безвинний аналіз інциденту після його усунення:
Observability — ширша концепція, ніж моніторинг. Три стовпи (метрики, логи, трейси) разом дають повну картину стану системи та дозволяють відповісти на питання «чому?» при виникненні інцидентів.
SLI/SLO/SLA та Error Budget — фундамент SRE-практик. Помилковий бюджет балансує між надійністю та швидкістю розробки.
CloudWatch, Azure Monitor та GCP Operations є потужними платформами моніторингу, що надають готові інтеграції з усіма сервісами своїх хмар. Для мультихмарних або K8s-середовищ — Prometheus+Grafana або Datadog.
Розподілене трасування (X-Ray, Jaeger, OTel) є незамінним для мікросервісних систем, де єдиний запит охоплює десятки сервісів.
Патерни відмовостійкості (Circuit Breaker, Retry, Bulkhead, Timeout, Graceful Degradation) та Multi-AZ розгортання — фундамент production-систем. Design for Failure та Chaos Engineering гарантують, що система витримає реальні збої.