Dead Letter Queue: לאן הולכות ההודעות שנכשלות שוב ושוב

מאת צוות מדיה דיל · 28.06.2026 · טכנולוגיה · 4 דק׳

Retry Policy, Exponential Backoff, Replay, Idempotency, Kafka Topics, ו-Alerting.

הודעה בתור מנסה להיכתב למסד נתונים, אבל הרשומה שהיא מתייחסת אליה נמחקה כבר. ה-consumer זורק exception, התור מנסה שוב מיד, נכשל שוב, מנסה שוב, ואותה הודעה אחת תקועה ב-retry אינסופי שחוסמת את כל שאר ההודעות שממתינות מאחוריה בתור, גם אם הן תקינות לגמרי. Dead Letter Queue (DLQ) הוא תור נפרד שאליו עוברות הודעות שנכשלו שוב ושוב, כדי שכשל בהודעה בודדת לא יעצור את כל קו העיבוד.

הבעיה: הודעה תקועה חוסמת את כל התור

ברוב מנגנוני התורים, אם consumer לא מאשר קבלה (ack) של הודעה, היא חוזרת לתחילת התור או נשלחת שוב מיד. בלי מגבלה, הודעה פגומה נכנסת ללולאה: נכשלת, חוזרת, נכשלת שוב, לנצח. במערכות עם עיבוד לפי סדר (ordered processing) זה חמור במיוחד, כי כל ההודעות שאחרי ההודעה התקועה ממתינות לתורן ולא מתקדמות בכלל, גם אם אין להן שום קשר לבעיה שגרמה לכשל בהודעה הראשונה.

Retry Policies: כמה פעמים ואיך

הפתרון מתחיל במדיניות retry מוגדרת מראש: מספר ניסיונות מקסימלי, ולרוב עם exponential backoff, השהיה שגדלה בין ניסיון לניסיון (למשל שנייה, שתי שניות, ארבע שניות) כדי לתת לבעיה זמנית (כמו עומס רגעי או תקלת רשת) הזדמנות להיעלם מעצמה בלי להציף את המערכת בניסיונות חוזרים צפופים. רק אחרי שמספר הניסיונות המקסימלי מוצה, ההודעה מסומנת ככשל קבוע ומועברת ל-DLQ במקום להמשיך לנסות שוב באופן שמונע התקדמות של כל השאר.

מה קורה בפועל ב-DLQ

הודעה שהגיעה ל-DLQ לא נעלמת, היא נשמרת שם עם metadata שמתעד כמה פעמים נוסתה, מה הייתה שגיאת הכשל האחרונה, ומתי זה קרה, כך שצוות אנוש או תהליך אוטומטי יכולים לבדוק את הסיבה בלי לחפור בלוגים. אחרי תיקון הבעיה השורשית, נניח באג בקוד ה-consumer או תיקון נתונים פגומים, אפשר לשלוח מחדש (replay) את ההודעות מה-DLQ בחזרה לתור הראשי לעיבוד, בלי לאבד אותן ובלי לחסום את שאר התור בזמן שהבעיה נחקרת.

Idempotency בעת Replay

שליחה חוזרת של הודעות מה-DLQ יוצרת סיכון: אם הודעה בכל זאת עובדה חלקית לפני הכשל, replay עלול לגרום לעיבוד כפול, חיוב כפול, משלוח כפול. לכן consumers שמטפלים בהודעות מ-DLQ חייבים לתמוך ב-Idempotency: מזהה ייחודי לכל הודעה שמאפשר לזהות אם היא כבר טופלה בעבר ולדלג עליה בבטחה, גם כשהיא מגיעה שוב אחרי ריצה חוזרת דרך ה-DLQ ולא רק בזרימה הרגילה של התור.

מימוש ב-Kafka ומערכות תורים אחרות

ב-Kafka, DLQ מיושם בדרך כלל כ-topic נפרד שאליו consumer שולח הודעות שנכשלו אחרי מספר ניסיונות, לרוב דרך framework כמו Kafka Connect עם dead letter queue config מובנה. בתורי הודעות מסורתיים כמו RabbitMQ או SQS, DLQ הוא לרוב תכונה מובנית של השירות עצמו, עם הגדרת maxReceiveCount שקובעת אחרי כמה כשלים ההודעה עוברת אוטומטית לתור המתים, בלי צורך במימוש ידני של ספירת ניסיונות בקוד האפליקציה.

ניטור: DLQ שאף אחד לא בודק הוא חסר תועלת

DLQ ריק כל הזמן זה טוב, אבל DLQ שמצטברות בו הודעות בלי שאף אחד שם לב הוא לא שונה בהרבה מזריקת ההודעות לפח, הבעיה השורשית ממשיכה להתרחש בלי שאף אחד יודע. לכן חיוני להגדיר alert על כל הודעה חדשה שנכנסת ל-DLQ, ולעבד אותה כתקרית שדורשת בדיקה תוך זמן קצוב, לא כארכיון סטטי שמצטבר עד שמישהו נתקל בו במקרה חודשים אחר כך.

הודעות נכשלות תוקעות לכם תורים שלמים בלי שאף אחד שם לב? נשמח לעזור לכם בוואטסאפ.

תגיות: Dead Letter Queue · DLQ · Retry Policy · Exponential Backoff · Kafka · Idempotency

← חזרה לבלוג · צור קשר