Alert Service — Redis + התראות סף
מה זה?
Analyzer עלול לזהות את אותה אנומליה כמה פעמים ברציפות (אם הערך החריג נשאר חריג לאורך כמה אירועים רצופים) — בלי הגנה, Alert Service היה שולח 10 התראות זהות למישהו, מטריד ומיותר. Redis (מיחידת NoSQL) פותר את זה: שומר “כבר התרענו על זה” עם TTL — אם אותה אנומליה מתגלה שוב תוך זמן קצר, לא שולחים התראה כפולה.
מילות מפתח שחשוב לזכור
• Deduplication (מניעת כפילות) — זיהוי שהתראה “כבר נשלחה” ומניעת שליחה חוזרת מיותרת
• Threshold Alert — התראה שנשלחת רק כשערך חוצה סף מוגדר מראש, לא על כל חריגה קטנה
• Alert Fatigue — תופעה אמיתית שבה יותר מדי התראות (כולל כפולות) גורמות למי שמקבל אותן להתעלם מכולן, כולל האמיתיות
// AlertService — consumes from Kafka, Deduplication with Redis
public class AlertConsumerService : BackgroundService
{
private readonly IDatabase _redis; // from the NoSQL unit
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var consumer = new ConsumerBuilder<Null, string>(config).Build();
consumer.Subscribe("anomaly-detected"); // matches the Contract from Analyzer
while (!stoppingToken.IsCancellationRequested)
{
var result = consumer.Consume(stoppingToken);
var finding = JsonSerializer.Deserialize<AnomalyFinding>(result.Message.Value);
string dedupeKey = $"alert:{finding.EventId}";
bool alreadyAlerted = await _redis.KeyExistsAsync(dedupeKey); // cache check, like Cache-Aside
if (!alreadyAlerted)
{
await SendAlert(finding);
await _redis.StringSetAsync(dedupeKey, "sent", TimeSpan.FromMinutes(10)); // TTL — don't send again for 10 minutes
}
}
}
private Task SendAlert(AnomalyFinding finding)
{
Console.WriteLine($"🚨 Alert: event {finding.EventId} exceeded the expected range!");
return Task.CompletedTask;
}
}הסבר עיקרי
BackgroundService — Consumer שרץ ברציפות, לא endpoint — בניגוד ל-Collector (שיש לו endpoint שמישהו קורא אליו), Alert Service מאזין ברציפות ברקע לכל אורך חיי האפליקציה — BackgroundService הוא הדפוס הסטנדרטי ב-ASP.NET Core לקוד שרץ ברקע (לא תגובה לבקשת HTTP ספציפית).
Deduplication עם Redis הוא Cache-Aside בהיפוך תפקידים — בשיעור Redis (מיחידת NoSQL) בדקנו “האם יש במטמון?” כדי לקצר תהליך; כאן בודקים “האם כבר שלחתי?” כדי למנוע פעולה כפולה. אותו כלי בדיוק (KeyExistsAsync+TTL), שימוש הפוך: לא חוסכים חישוב, מונעים חזרתיות מיותרת.
Threshold, לא כל חריגה — Analyzer כבר “סינן” חריגות (2 סטיות תקן), אבל Alert Service יכול להוסיף שכבת סף נוספת משלו — למשל, להתריע רק אם חריגה חוזרת 3 פעמים תוך דקה, לא על חריגה בודדת. זה מונע Alert Fatigue — יותר מדי התראות “אמיתיות אך לא-קריטיות” שגורמות למי שמקבל אותן להתעלם מהכל, כולל האמיתי-חשוב.
יתרונות
Redis Deduplication מונע הצפת התראות זהות; BackgroundService נותן דפוס נקי לצריכה רציפה ברקע; שכבת Threshold נוספת מפחיתה Alert Fatigue.
חסרונות
TTL קבוע מדי (10 דקות בדוגמה) עלול להחמיץ הידרדרות אמיתית שממשיכה מעבר לחלון הזה; אם Redis לא זמין, Deduplication נכשל בשקט (או חוסם התראות לגמרי, תלוי במימוש) — נדרש טיפול שגיאות מפורש.
נקודות חשובות
• Deduplication מונע התראות כפולות על אותו אירוע תוך זמן קצר, עם Redis+TTL
• BackgroundService הוא הדפוס הסטנדרטי לצריכת Kafka רציפה ב-ASP.NET Core
• Alert Fatigue הוא סיכון אמיתי — יותר מדי התראות (גם אמיתיות) פוגעות באפקטיביות שלהן
• זהו אותו מנגנון Cache-Aside מיחידת Redis, בשימוש הפוך (מניעת חזרה, לא חיסכון חישוב)
טעויות נפוצות
• לשלוח התראה על כל הודעת אנומליה בלי Deduplication — הצפה מהירה של אותה בעיה שוב ושוב
• לבחור TTL קצר/ארוך מדי בלי לחשוב על טבע הבעיה שמנטרים
• לא לטפל בכישלון Redis (חיבור נכשל) — עלול לחסום כל התראה עתידית או להציף בלי הגנה, תלוי בכיוון הכישלון
סיכום
Alert Service צורך ממצאי אנומליה מ-anomaly-detected (תואם ל-Contract מ-Analyzer) דרך BackgroundService, ומשתמש ב-Redis Deduplication (KeyExistsAsync+TTL) כדי למנוע התראות כפולות על אותה בעיה תוך זמן קצר — אותו מנגנון Cache-Aside מיחידת Redis, בכיוון הפוך. שכבת Threshold נוספת יכולה למנוע Alert Fatigue — יותר מדי התראות שגורמות להתעלמות מהאמיתיות.
דוקומנטציה רשמית
Microsoft Learn — BackgroundService
תרגילים
תרגיל 1 — Deduplication בסיסי
המשימה: כתבו פונקציה bool ShouldAlert(string key) שבודקת Redis, ומחזירה true פעם ראשונה בלבד לכל key תוך TTL של דקה.
בדיקה: קריאה ראשונה מחזירה true; קריאה שנייה תוך פחות מדקה על אותו key מחזירה false; אחרי דקה, true שוב.
תרגיל 2 — BackgroundService מינימלי
המשימה: כתבו BackgroundService שמדפיס “בדיקה…” כל 5 שניות (בלי Kafka עדיין), והריצו אותו כחלק מ-ASP.NET Core app.
בדיקה: ההודעה מודפסת ברציפות ברקע, גם בלי בקשת HTTP נכנסת כלשהי.
פרויקט מסכם
המשימה: ממשו את Alert Service המלא לפי ה-Contract שהצוות כתב.
דרישות:
BackgroundServiceשצורך מ-anomaly-detected- Deduplication עם Redis, TTL סביר (5-10 דקות)
- הדפסת/רישום התראה ברורה עם פרטי האירוע (לא רק “יש בעיה”)
בדיקה: שליחת אותה אנומליה כמה פעמים ברצף (דרך Collector+Analyzer) מייצרת התראה אחת בלבד; אחרי TTL, אותה אנומליה בדיוק כן מייצרת התראה נוספת.
מה בפרק הבא
בפרק הבא — Dashboard Service: השירות הרביעי והאחרון — מציג תמונת מצב מצטברת מכל שאר השירותים, בפייתון.