🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ
فرض کن ساعت ۳ صبح است.
سیستم شما با ۲۰۰۰ Request در ثانیه کار میکند. یکدفعه:
Error Rate ↑
Latency ↑
CPU ↑
DB Connections ↑
Queue Depth ↑
و چند ثانیه بعد:
📱 47 Alert
📱 132 Alert
📱 580 Alert
تیم On-Call گوشی را برمیدارد و با خودش میگوید:
«خب دقیقاً کدومش مشکل اصلیه؟! 😐»
اینجا متوجه میشویم که داشتن Monitoring با داشتن Observability و Alerting درست فرق دارد.
1️⃣ ءMetrics؛ سیستم الان چه وضعیتی دارد؟
Metric یک اندازهگیری عددی از وضعیت سیستم است.
مثلاً:
http_requests_total
http_request_duration
http_errors_total
cpu_usage
memory_usage
queue_depth
active_connections
مثلاً:
Request Rate = 5000 req/s
Error Rate = 4.2%
P99 Latency = 2.8s
ءMetric برای جوابدادن به سؤالهایی مثل این عالی است:
«الان سیستم سالم است؟»
2️⃣ ءLogs؛ چه اتفاقی افتاد؟
ءLog معمولاً یک Event یا Record مربوط به اتفاقی است که در سیستم رخ داده.
مثلاً:
{
"level": "Error",
"message": "Payment failed",
"orderId": "12345",
"paymentProvider": "X",
"traceId": "abc-123"
}ءLog به ما Context بیشتری میدهد.
مثلاً Metric میگوید:
Payment Error Rate = 8%
ولی Log میتواند نشان دهد:
PaymentProviderTimeout
OrderId = 12345
Provider = X
TraceId = abc-123
3️⃣ ءTrace؛ درخواست از کجا عبور کرد؟
فرض کن کاربر این Request را ارسال میکند:
POST /orders
ءRequest وارد سیستم میشود:
API
↓
Order Service
↓
Payment Service
↓
Inventory Service
↓
Database
ءTrace میتواند مسیر این Request را نشان دهد:
Trace
│
├── API 20ms
│
├── Order Service 35ms
│
├── Payment Service 800ms
│ │
│ └── Provider 780ms
│
└── Inventory 25ms
حالا میفهمیم مشکل دقیقاً کجاست.
🎯 اما Monitoring بهتنهایی کافی نیست
فرض کن این Metric را داریم:
CPU = 92%
آیا باید Alert بزنیم؟ لزوماً نه.
ممکن است:
CPU = 92%
Latency = normal
Error Rate = normal
Users = happy
در این حالت CPU بالا الزاماً به معنی Incident نیست.
حالا سناریوی دیگری:
Error Rate = 8%
P99 Latency = 4s
اینجا احتمالاً کاربران واقعاً مشکل دارند.
پس یک اصل مهم در Alerting این است:
تا جای ممکن روی Symptomای Alert کن که نشاندهندهی User Impact است، نه روی تکتک علتهای احتمالی.
ءPrometheus نیز در راهنمای Alerting خود توصیه میکند تا حد امکان روی Symptoms مرتبط با User Pain هشدار بدهیم و از Alertهایی که هیچ اقدام مشخصی به دنبال ندارند دوری کنیم.
🚨 پس چه چیزهایی را Alert کنیم؟
مثلاً برای یک API:
High Error Rate
High Latency
Service Unavailable
Queue Backlog
Database Saturation
Capacity Exhaustion
مثلاً:
Error Rate > 5%
for 5 minutes
یا:
P99 Latency > 2 seconds
for 10 minutes
اما این عددها Universal نیستند.
Threshold باید بر اساس:
SLO
Traffic Pattern
Business Requirement
Capacity
Historical Behavior
تعیین شود.
⏳ چرا
for مهم است؟فرض کن CPU برای یک لحظه میشود:
92%
اگر همان لحظه Alert بفرستیم:
🚨 CPU HIGH!
ممکن است فقط یک Spike چندثانیهای بوده باشد.
بهتر است بگوییم:
CPU > 90%
for 10 minutes
یعنی شرط باید مدتی پایدار بماند.
ءPrometheus برای Alert Rule چنین مفهومی را با
for پشتیبانی میکند؛ Alert ابتدا Pending میشود و اگر شرط برای مدت تعیینشده برقرار بماند، وارد حالت Firing میشود. همچنین keep_firing_for برای کاهش بعضی Flappingها قابل استفاده است.🧠 ءAlert خوب چه شکلی است؟
این Alert:
🚨 API Error Rate High
خیلی مفید نیست. On-Call باید دوباره برود بگردد:
کدام API؟
کدام Environment؟
کدام Region؟
از کی؟
چقدر؟
چرا؟
ءAlert بهتر:
🚨 High API Error Rate
Service: Payment
Environment: Production
Region: EU
Error Rate: 8.4%
Threshold: 5%
Started: 03:12 UTC
Dashboard: ...
Runbook: ...
Trace: ...
خود Prometheus هم برای Alertها امکان استفاده از Labels و Annotations را فراهم میکند تا اطلاعاتی مثل Summary، Description و لینک Runbook همراه Alert قرار بگیرد.