איך לתכנן dead-letter queue לחריגים שלא נפתרו ב-retry
אינטגרציות · אוקטובר 2026
מדריך לתכנון DLQ באינטגרציה: סיווג כשלים, תנאי מעבר, בעלות, טיפול מאובטח, תיקון, replay מבוקר, מניעת כפילויות ומדדי תפעול.
קטגוריה: אינטגרציות | תאריך: אוקטובר 2026
כאשר אינטגרציה נכשלת בגלל timeout או תקלה זמנית, ניסיון חוזר הוא בדרך כלל תגובה סבירה. אבל לא כל כשל נפתר ב-retry: מסמך יכול להגיע בלי שדה חובה, לקוח לא קיים במערכת היעד, הרשאה חסרה או כלל עסקי דוחה את הפעולה. אם ממשיכים לנסות ללא גבול, מצטברים עומס, רעש וכפילויות אפשריות. אם מפסיקים בלי לשמור הקשר, הבקשה נעלמת מהתהליך.
dead-letter queue, או בקיצור DLQ, הוא אזור מבודד לפריטים שהתהליך הרגיל לא הצליח לעבד לפי המדיניות שהוגדרה. הוא אינו פח אשפה ואינו פתרון לכשל בפני עצמו. DLQ שימושי רק כאשר ברור למה פריט הגיע אליו, מי אחראי לבדוק אותו, איזה מידע מותר להציג, כיצד מתקנים את הסיבה ואיך מחזירים את הפריט לעיבוד בלי לבצע שוב פעולות שכבר הצליחו.
קודם להפריד בין כשל זמני לכשל שדורש טיפול
לא נכון לשלוח כל שגיאה מיד ל-DLQ, וגם לא נכון לבצע retry לכל שגיאה. לפני התכנון כדאי לסווג כשלים לפי המשמעות העסקית והטכנית שלהם:
- כשל זמני: timeout, חוסר זמינות רגעי או מגבלת קצב. אפשר לנסות שוב לפי מדיניות מוגבלת.
- כשל קבוע בקלט: שדה חסר, ערך לא חוקי או schema שאינו נתמך. retry עם אותו קלט לא ישנה את התוצאה.
- כשל עסקי: הישות אינה במצב שמאפשר פעולה, חסר אישור או קיימת סתירה מול מקור האמת.
- כשל הרשאה או תצורה: credential, scope, endpoint או feature flag אינם תואמים לסביבה.
- כשל לא מסווג: שגיאה חדשה שאינה מתאימה לקוד מוכר ודורשת חקירה.
לכל סוג מגדירים פעולה. כשל זמני יכול לעבור מספר ניסיונות עם השהיה; קלט לא תקין יכול לעבור לחריג מיד; בעיית תצורה עשויה להצדיק עצירת צרכן שלם ולא יצירת אלפי פריטי DLQ זהים. המדריך על טיפול ב-retry וכשלונות באוטומציה מסייע להגדיר backoff, מספר ניסיונות ותנאי עצירה.
להגדיר במפורש מתי פריט עובר ל-DLQ
תנאי המעבר צריכים להיות חלק מחוזה התהליך, ולא ברירת מחדל נסתרת של כלי התורים. אפשר להגדיר מעבר לאחר מספר ניסיונות מוגבל, עם קבלת קוד שגיאה שאינו ניתן ל-retry, לאחר תפוגת חלון עסקי או כאשר payload אינו עובר ולידציה.
כדאי לשמור בעת המעבר:
- מזהה הודעה ומזהה מעקב של התהליך.
- סוג האירוע וגרסת ה-schema.
- זמן הקליטה, זמן הניסיון האחרון ומספר הניסיונות.
- קוד שגיאה יציב ושלב העיבוד שנכשל.
- מזהה עסקי מצומצם או הפניה מאובטחת לרשומה.
- גרסת הרכיב והתצורה הרלוונטית לחקירה.
- רשימת פעולות שכבר בוצעו, אם התהליך כולל כמה שלבים.
אין צורך להעתיק ל-DLQ token, סיסמה, headers מלאים או payload רגיש רק כדי להקל על הבדיקה. לעיתים עדיף לשמור הפניה מוצפנת או מזהה לרשומה במאגר מורשה. מדיניות שמירת נתונים ולוגים צריכה לחול גם על תור החריגים, כולל הרשאות, תקופת שמירה ומחיקה.
לבנות בעלות ותור עבודה, לא רק תור טכני
פריט ב-DLQ צריך להפוך לעבודה שניתנת לניהול. לכל קוד שגיאה או סוג תהליך מגדירים בעלים: צוות אינטגרציה, בעל תהליך עסקי, מנהל נתונים או צוות שמנהל את מערכת היעד. אין צורך שכל גורם יראה את תוכן ההודעה; מסך תפעולי יכול להציג את פרטי החריג הנדרשים לתפקיד ולהפנות למידע נוסף לפי הרשאה.
לכל פריט רצוי לנהל סטטוס ברור, למשל: חדש, בבדיקה, ממתין לתיקון מקור, מוכן ל-replay, הוחזר בהצלחה או נסגר ללא עיבוד. לצד הסטטוס שומרים בעלים, סיבת החלטה וזמן שינוי. כך ה-DLQ אינו הופך לרשימה הולכת וגדלה שאין דרך לדעת מי מטפל בה.
גם התראות צריכות להיות מצטברות וחכמות. הודעה על כל פריט יכולה ליצור הצפה בזמן תקלה רוחבית. עדיף לזהות קפיצה לפי תהליך וקוד שגיאה, להציג את מספר הפריטים ואת הפריט הראשון לדוגמה, ולפתוח אירוע אחד עם קישור לרשימה המסוננת.
להבחין בין תיקון הפריט לתיקון המערכת
לפני החזרה לעיבוד צריך להבין מה השתנה. קיימים כמה מסלולים שונים:
- תיקון נתון במקור: מתקנים את הרשומה במערכת המוסמכת ומייצרים אירוע חדש או מאשרים replay של האירוע הקיים.
- תיקון מיפוי או קוד: פורסים גרסה מתוקנת ואז בודקים את הפריט מול הגרסה החדשה.
- תיקון הרשאה או תצורה: מאמתים שהחיבור עובד באמצעות בדיקה מצומצמת לפני פתיחת הזרימה.
- החלטה עסקית: גורם מורשה בוחר אם להשלים, לדחות או לסגור את הבקשה.
עריכה ידנית של payload בתוך מסך DLQ עלולה לנתק את הפריט ממקור האמת ולהקשות על ביקורת. אם חייבים לאפשר שינוי, שומרים את הערך המקורי, הערך המתוקן, זהות המאשר וסיבת השינוי, ומגבילים את השדות שניתנים לעריכה.
לתכנן replay שלא משכפל פעולות שכבר הצליחו
החזרת הודעה לתור הראשי אינה פעולה תמימה. ייתכן שחלק מהתהליך כבר בוצע לפני הכשל: רשומה נוצרה ב-SAP, מסמך נשמר או משימה נפתחה. replay עיוור עלול לחזור על הפעולה ולהשאיר מצב מורכב יותר מהכשל המקורי.
לפני replay יש לבדוק מהי יחידת העבודה ומה נשמר מהניסיון הקודם. פעולות כתיבה צריכות להשתמש במפתח idempotency או לבדוק את המצב הקיים לפני ביצוע. המאמר על מניעת עיבוד כפול באמצעות idempotency מפרט כיצד לבחור מפתח ולשמור תוצאה לאורך ניסיונות.
בתהליך רב-שלבי אפשר להחזיר את הפריט מהשלב שנכשל, אם נשמר checkpoint אמין, או להריץ מחדש מתחילת התהליך כאשר כל הפעולות בטוחות לחזרה. אין לבחור מסלול רק לפי נוחות טכנית; צריך להוכיח מה קורה לכל side effect שכבר בוצע.
להוסיף מצב dry run ו-replay מדורג
כאשר מתקנים תקלה שהכניסה פריטים רבים ל-DLQ, לא כדאי להחזיר את כולם בבת אחת. תחילה מפעילים dry run שמבצע parsing, validation, מיפוי ובדיקת תנאים בלי לכתוב למערכות יעד. לאחר מכן בוחרים קבוצה קטנה ומייצגת, מריצים אותה, בודקים תוצאות עסקיות ורק אז מרחיבים.
מנגנון replay צריך לתמוך בסינון לפי סוג אירוע, קוד שגיאה, גרסת schema, טווח זמן ומערכת יעד. חשוב לשמור מזהה replay, מי אישר אותו, אילו פריטים נכללו ומה הייתה התוצאה של כל אחד. correlation ID לאורך כמה מערכות עוזר לקשר בין הניסיון המקורי לניסיון המתוקן, אך אינו מחליף מזהה replay או מנגנון מניעת כפילות.
אם הפריטים תלויים זה בזה, צריך לשמור סדר או תנאי קדימות. לדוגמה, עדכון לישות אינו יכול להקדים את יצירתה. החזרה מקבילית של כל הפריטים עלולה ליצור כשלים חדשים גם כאשר כל הודעה תקינה בפני עצמה.
למדוד את בריאות ה-DLQ ואת בריאות התהליך
מספר הפריטים הכולל הוא מדד חלקי בלבד. כדאי לעקוב אחר:
- קצב כניסה לפי תהליך וקוד שגיאה.
- גיל הפריט הוותיק ביותר וזמן חציוני עד טיפול.
- מספר פריטים שחזרו בהצלחה לעומת אלה שנכשלו שוב.
- כשלים חוזרים אחרי replay ואותה סיבת שורש.
- פריטים שמתקרבים לתום תקופת השמירה.
- כמות חריגים פתוחים לפי בעלים וסטטוס.
- שיעור הכשלים מתוך כלל הפעולות, כדי לא לבלבל גידול פעילות עם הידרדרות איכות.
קפיצה רגעית יכולה להעיד על השבתת יעד; זרם קטן וקבוע עשוי לחשוף בעיית נתונים שלא טופלה. המטרה אינה רק לרוקן את התור, אלא לצמצם את הסיבה שיוצרת את החריגים. כאשר אותו קוד חוזר, צריך להחליט אם לשפר ולידציה מוקדמת, לעדכן מיפוי, להבהיר כלל עסקי או לשנות את התהליך.
בדיקות שכדאי לבצע לפני ייצור
- timeout זמני שמצליח בתוך מדיניות ה-retry ואינו מגיע ל-DLQ.
- payload לא תקין שעובר ל-DLQ עם קוד שגיאה ברור וללא מידע רגיש.
- תקלה רוחבית שמייצרת התראה מצטברת ואינה מציפה את הצוות.
- תיקון קלט במקור והחזרה מבוקרת של פריט יחיד.
- replay לאחר ששלב קודם כבר הצליח, בלי יצירת פעולה כפולה.
- dry run שמזהה בעיה נוספת בלי לכתוב למערכת יעד.
- replay מדורג של קבוצה, כולל עצירה כאשר שיעור הכשל עולה.
- פריט עם גרסת schema ישנה שנבדק מול consumer מעודכן.
- משתמש ללא הרשאה שאינו יכול לראות payload או להפעיל replay.
- מחיקה או ארכוב לפי המדיניות תוך שמירת תיעוד ההחלטה הנדרש.
בכל תרחיש בודקים גם את התוצאה העסקית במערכת היעד, ולא מסתפקים בכך שההודעה נעלמה מה-DLQ.
שאלות נפוצות
האם צריך DLQ לכל תור?
לא בהכרח. צריך מסלול ברור לכל פריט שלא ניתן לעבד. בתהליך קטן הוא יכול להיות טבלת חריגים או מסך עבודה. הבחירה תלויה בארכיטקטורה, אך הדרישות של בידוד, הקשר, בעלות, תיקון ו-replay נשארות דומות.
האם אפשר למחוק פריט אחרי replay מוצלח?
אפשר להסיר אותו מהתור הפעיל לפי מדיניות השמירה, אך כדאי לשמור תיעוד מצומצם של הסיבה, האישור והתוצאה. אין לשמור payload רגיש ללא צורך עסקי או חוקי מאושר.
מה עושים עם poison message שחוזר ל-DLQ שוב ושוב?
מגבילים את מספר מחזורי ה-replay, מסמנים את הפריט ככשל חוזר ודורשים בדיקה חדשה לפני ניסיון נוסף. החזרה אוטומטית אינסופית רק מעבירה את הלולאה בין התור הראשי ל-DLQ.
האם DLQ מחליף reconciliation?
לא. DLQ מטפל בפריטים שהמערכת זיהתה ככושלים. reconciliation בין מערכות נדרש גם כדי למצוא פערים שלא יצרו שגיאה גלויה, למשל פעולה שסומנה כהצלחה אך לא הושלמה במערכת היעד.
להתחיל מסוג חריג אחד
בחרו תהליך אחד ושגיאה אחת שאינה נפתרת ב-retry. הגדירו את תנאי המעבר ל-DLQ, המידע המצומצם שנשמר, הבעלים, מסלול התיקון, תנאי ה-replay ובדיקת התוצאה העסקית. לאחר מכן הריצו כשל מבוקר והוכיחו שאפשר לאתר את הפריט, להבין מדוע נעצר, לתקן אותו ולהחזיר אותו בלי כפילות ובלי לחשוף מידע שאינו נדרש.
Adaptico מסייעת בתכנון אינטגרציות, workflows ומסכי בקרה לתהליכים ארגוניים, כולל טיפול בחריגים, retries ו-replay מבוקר. אפשר [ליצור קשר](/#contact) כדי למפות תהליך אחד ולתכנן עבורו מסלול חריגים שניתן לתפעל ולבקר.