מדוע Correlation ID הולך לאיבוד בין מיקרו-שירותים
Correlation ID נולד בדרך כלל ממש בתחילת הנתיב: reverse proxy או שער כניסה מקצה מזהה לבקשה ומכניס אותו לכותרת. בקריאות סינכרוניות הוא עובר בצורה מדויקת — כל שירות קורא את הכותרת ומוסיף את הערך לרשומות הלוג שלו. כל עוד שרשרת הקריאות לינארית, נראה שמעקב אחר מיקרו-שירותים הוא משימה פתורה.
הקרע מתרחש כבר במעבר האסינכרוני הראשון. השירות מפרסם הודעה לתור או מציב משימה מושהית, אך המזהה נשאר בהקשר של המטפל שהציב את המשימה, ואינו נכנס לתוך ההודעה עצמה.
המטפל בצד השני פותח שרשרת חדשה עם ערך ריק — והשרשרת מקצה לקצה נקרעת בדיוק במקום שבו מתחיל החלק הכי לא טריוויאלי: ניסיונות חוזרים, עיבוד חוזר, חיובים מושהים.
המחיר מתגלה בעת חקירת אירוע. בלוגים של חמישה שירותים מונחות מאות רשומות, ואפשר לקשר ביניהן רק לפי זמן וגוף הבקשה. השעונים בין השירותים אינם מסונכרנים, בקשות זהות יש עשרות בדקה, ואובדן מזהה הבקשה משמעו שאין כל קשר בין הרשומות.
מהנדסים עוברים ידנית על הלוגים ומצליבים חתימות זמן, וכל תקלה גובה כמה שעות עבודה של שניים-שלושה אנשים.
נקודה כואבת במיוחד היא שחלק מהאירועים נסגרים בנוסח "לא ניתן לשחזר": הסיבה נשארת במערכת ומתרחשת שוב. הבעיה כאן אינה היעדר כלים, אלא שהערך לא שורד את גבול ההקשר — תור, מטפל ברקע, משימה מושהית. נסביר כיצד סוגרים את זה.
מה נותן מעקב מקצה לקצה אחר בקשות
בלי מעקב מקצה לקצה, חקירת אירוע הופכת להצלבת לוגים לפי חתימות זמן. המהנדס עובר על חמישה-שבעה שירותים, מצליב רשומות ידנית ובכל זאת אינו רואה באיזה שלב הבקשה אבדה. Correlation ID פותר זאת: המזהה נולד בכניסה ומועבר בכל הקריאות — מהשער ועד לתור ההודעות ולמשימת הרקע.
שרשרת אירועים אחידה במקום לוגים מפוזרים
המזהה מוכנס לכותרת הבקשה הנכנסת, מועבר לקריאות בין-שירותיות ולמטא-נתונים של הודעות הברוקר, ומגיע להקשר של משימות מושהות. אספן הלוגים מאנדקס אותו כשדה נפרד — שאילתה אחת לפי הערך מפיקה כרונולוגיה מלאה של הבקשה בכל השירותים, כולל תגובות ושגיאות.
אנחנו מאחדים את פורמט ההקשר לצורה אחידה: בלי זה חלק מהשירותים מאבדים את המזהה בהעברה אסינכרונית. שומרים על תאימות לתקן הנפוץ OpenTelemetry, כדי לקשר את המעקב למטריקות ולא להמציא כללים משלנו.
כיצד מודדים את האפקט
שתי מטריקות: שיעור הבקשות עם שרשרת מלאה — נמדד לפי מספר המזהים שיש להם אירועים לאורך כל הנתיב, והזמן עד לזיהוי הגורם לתקלה. השני יורד מעשרות דקות של הצלבה ידנית לכמה דקות של שאילתה.
הנראות של השירותים מפסיקה להיות תלויה במי מהמהנדסים שמכיר את טופולוגיית הקריאות: השרשרת נקראת ישירות מהלוגים.
אפשרויות להעברת המזהה בין שירותים
Correlation ID נולד בגבול האמון — במקום שבו הבקשה נכנסת לראשונה למערכת שלנו: reverse proxy, שער או השירות הראשון בשרשרת. אם לא מקבעים כלל, כל שירות ייצור ערך משלו, ולא יהיה במה לקשר בין האירועים בלוגים. מכאן השאלה היחידה היא: כיצד המזהה שורד את המעבר בין תהליכים ותורים.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| כותרת בקשה | קריאות סינכרוניות בין שירותים | הולך לאיבוד בהפניות ובפרוקסי ביניים |
| שדה בהודעת התור | עיבוד אסינכרוני ומשימות מושהות | תלוי בפורמט ההודעה, קל לשכוח למלא |
| שכבת ביניים להקשר הבקשה | שירותים רבים, נדרש אמצעי אחיד | שינויים בכל השירותים, יש לשמר את ההקשר בתוך התהליכון |
| העברה ידנית כפרמטר | אינטגרציות חד-פעמיות ובדיקות | מצטברות נקודות שכחו, לא בכל מקום אפשר לשנות חתימה |
היכן המזהה נולד
הוא נולד בצומת הכניסה: זה או מקבל ערך מהלקוח, אם הבקשה הגיעה ממקור מהימן, או מייצר ערך משל עצמו. אסור לקבל ערך זר מבחוץ — שרשראות מזויפות, והלוגים מזדהמים. כדאי לשרטט את גבול האמון באופן מפורש: שירותים פנימיים סומכים זה על זה, ההיקף החיצוני — לא.
כיצד המזהה חי בתורים
במסלול האסינכרוני המזהה נוסע במאפייני ההודעה, ולא בכותרות הבקשה — להודעה אין כותרות. המטפל משחזר את ההקשר בעת הקריאה ומחזיר אותו בעת פרסום האירוע הבא. בניסיונות חוזרים ובהעברה לתור הודעות שלא עובדו, הערך נשמר, ולכן הענף התקול נשאר מקושר לבקשה המקורית.
הטמעת Correlation ID: שלבי העבודה ההנדסית
סדר העבודות כאן אינו פורמליות: אם בוחרים נקודת יצירה שגויה למזהה, יהיה צורך לחפש כפילויות וקרעים בשרשראות מחדש בכל המערכת. לכן מתחילים בסקר, ומסיימים בהעברה לתפעול עם נוהל מוכן.
סקר ומפת קריאות
- עורכים מיפוי שירותים ובונים מפת קריאות: שרשראות סינכרוניות, תורי הודעות, משימות רקע ומתזמנים — כל מקום שבו הבקשה עלולה לאבד את ההקשר.
- מקבעים את נקודות היצירה של המזהה: הוא נולד פעם אחת בכניסה למערכת, ובפנים — רק מועבר הלאה בלי להיווצר מחדש בחוליות ביניים.
- מתאמים פורמט אחיד למזהה וכללים להעברתו דרך כותרות הבקשה והקשר ההרצה, כולל ענפים אסינכרוניים.
בדיקה והעברה לתפעול
- מתקנים את הלוגים והמעקב: המזהה נכנס לכל רשומה, כולל שגיאות והודעות של ספריות צד שלישי.
- בודקים את המעקב על תקלות משוחזרות — חריגה בזמן התגובה, ניתוק חיבור, מסירה חוזרת: השרשרת צריכה להיאסף בשאילתה אחת ללוגים.
- מודדים את התקורה וההתנהגות תחת עומס, כדי שהמזהה לא יהפוך לצוואר בקבוק בנתיב החם.
- מעבירים לתפעול: נוהל לחקירת אירועים, תבניות שאילתה מוכנות ללוגים, הדרכת המשמרת התורנית.
מערך ארטיפקטים ונהלים למעקב
לאחר הטמעת מעקב מקצה לקצה נותר לצוות לא רק קוד עובד, אלא גם מערך ארטיפקטים: לפיהם מהנדס תורן ומפתח חדש חוקרים אירוע בלי המחבר של השינוי. המערך חי במאגר הקוד ובבסיס הידע הפנימי ומתעדכן יחד עם השירותים.
סכמות וכללי שמות לשדות
- סכמת מעבר הבקשה — נקודות כניסה, קריאות סינכרוניות וקטעים אסינכרוניים: היכן המזהה נוצר, היכן מועבר הלאה, היכן משוחזר מהכותרת.
- כללי שמות לשדות — שם אחיד לכותרת, לשדה בלוג ולמתווית במטריקות בכל השירותים: השרשרת נאספת בשאילתת חיפוש אחת.
- הסכמה על פורמט המזהה — יצירה בכניסה, ייצוג בלוגים, התנהגות בהיעדר כותרת מלקוח חיצוני.
- סכמת קישורים למשימות רקע — התאמה בין מזהי הבקשה והפעולה המושהית, כדי שהשרשרת לא תיקרע בתורים.
נוהל המשמרת התורנית
- הוראות לתורן — מאיזה שירות מתחילים את החקירה, אילו שדות בודקים, כיצד לאסוף שרשרת מלאה לפי מזהה אחד.
- הגדרות אספן הלוגים — שדות מאונדקסים, תקופת שמירה, כללי פרסור ומיסוך נתונים רגישים.
- תיעוד המעקב — תיאור השדות, דוגמאות שאילתות, מגבלות ידועות, סדר חיבור שירות חדש.
- צ'ק-ליסט קבלה — תרחיש עם קרע בשרשרת ובדיקת מעבר מקצה לקצה דרך קטע אסינכרוני.
מקרה בוחן: איתור סיבת התקלה התקצר פי שמונה
איך היה לפני ההטמעה
כל שירות כתב ללוג משלו, ולא היה מזהה בקשה משותף ביניהם. כשהגיעה תלונה "הבקשה לא נוצרה", המהנדס פתח את הלוגים בזה אחר זה — השער, שירות ההזמנות, החיוב, תור ההודעות — והצליב רשומות לפי זמן ולפי מספר משתמש.
חפיפה בזמן יצרה קשרים שגויים: בשנייה אחת עוברות עשרות בקשות במערכת, ואת הזוג "מי קרא למי" היה צריך לנחש.
חקירת פנייה אחת נמשכה בין שעתיים לארבע, וחלק מהסיבות כלל לא נמצאו — האירוע נסגר עם השחזור, בלי סיבת שורש. שיעור התקלות מסוג "לא ניתן לשחזר" הגיע לשליש מהפניות.
מה שינינו ומה נהיה
הטמענו Correlation ID מקצה לקצה: הוא נוצר בכניסה, מועבר בכל הקריאות, כולל אסינכרוניות — כותרות קריאה, מטא-נתונים של הודעות תור, הקשר של משימות רקע — ונכנס לכל רשומת לוג. מעל זה הגדרנו איסוף שרשראות מקושרות ב-Grafana, כך שמזהה אחד נפרש לעץ קריאות עם משך כל שלב.
זמן חקירת הפנייה ירד משעתיים-ארבע שעות ל-15-25 דקות — פי שמונה לפי החציון. שיעור האירועים בלי סיבה שנמצאה הצטמצם מ-30% ל-4%: בדיקת השערות בלוגים אורכת כעת דקות, כי סינון לפי מזהה אחד מחזיר את כל השרשרת במקום שורות מפוזרות.
גם עבודות התחזוקה המתוכננות השתנו באופן מורגש. לפני שחרור אנחנו מריצים תרחישי בקרה ומאמתים שהמזהה לא הולך לאיבוד באף קטע — בדיקות כאלה תופסות קרעים במעקב בענפים אסינכרוניים, שבהם קודם לכן שגיאות צפו רק בסביבת העבודה.
במה שונה מעקב מקצה לקצה מתיעוד לוגים
הלוג של השירות מתעד את מה שקרה בתוך תהליך אחד: זמן, רמה, הודעה, לפעמים מזהה משתמש. הרשומה נשארת מקומית — היא לא יודעת דבר על השירות השכן שעיבד את אותה בקשה באלפית השנייה שלאחר מכן.
מעקב מקצה לקצה מתחיל במקום שבו אנחנו מקצים לבקשה Correlation ID בכניסה ומעבירים אותו הלאה בכל שרשרת הקריאות, כולל תורים, משימות רקע ומטפלים מושהים.
רמות הלוגים עונות על שאלה אחרת — עד כמה לפרט בכתיבה. העברת שירות מ-info ל-debug מוסיפה פרטים בנקודה נפרדת, אבל אם האירועים משירותים שונים אינם מקושרים במזהה משותף, הפרטים הללו עדיין אינם מתחברים לתמונה. הרמה שולטת בנפח וברעש, המעקב — בקישוריות. האחד אינו מחליף את השני: לוג מפורט אך לא מקושר נותן ערמת שורות שאין ביניהן קשרי סיבה ותוצאה.
המזהה צריך לשרוד גבולות: כותרת הבקשה הנכנסת, הקשר ההרצה, שדה במשימה לתור, תג ברשומת הלוג. אז הקשר הבקשה — מי קרא, איזו פעולה, איזה לקוח, איזו גרסת בנייה — משוחזר בסינון אחד.
בלי זה החיפוש נעשה לפי זמן, והעומס המקבילי הראשון או ניסיון חוזר שוברים את השאילתה: השורות של שתי בקשות מתערבבות, והחקירה הופכת לשחזור ידני.
האפקט המעשי מתגלה באבחון של מערכות מבוזרות. כשהאירוע נחקר לפי מזהה, המהנדס רואה את כל השרשרת מנקודת הכניסה ועד השירות האחרון ומוצא את מקום התקלה בדקות, ולא בשעות של תיאומים בין צוותים.
אם המזהה לא מגיע לקטע כלשהו — גם זה אות: כאן הקשר הולך לאיבוד, וקטע כזה צריך לכסות בנפרד בהעברת התג.
התלבטויות לגבי ההטמעה: מענה על שאלות הנדסיות
Correlation ID מוקצה בנקודת הכניסה ומועבר הלאה לאורך שרשרת הקריאות. לפני שמתחילים עולים בדרך כלל אותן שאלות: היכן לתקן את הקוד, מה לעשות עם לוגים של צוותים שונים והאם זמן התגובה ייפגע. להלן תשובות קצרות; תרחיש לא סטנדרטי נבחן בנפרד בשלב ההערכה.
האם נצטרך לשכתב שירותים?
לא. המזהה מוקצה בכניסה ומועבר בכותרת הקריאה. בשירותים מתקנים רק את שכבת הבקשות היוצאות — בדרך כלל מיירט אחד לשירות, והשאר עובדים בלי שינויים.
מה עושים עם פורמטים שונים של לוגים?
המזהה מתווסף להקשר הרשומה, ולא לטקסט ההודעה — כך נוצר שדה משותף בזמן הכתיבה. קבצים ישנים איננו משכתבים: הרשומות החדשות ממילא מודבקות לשרשרת אחת.
כיצד המזהה עובר עיבוד אסינכרוני?
הוא נכנס לכותרות ההודעה בעת ההצבה בתור ומשוחזר מהן בעת הקריאה. ניסיונות חוזרים שומרים על אותו מזהה, ולכן כולם נראים כבקשה אחת ולא כאירועים מפוזרים.
האם זמן העיבוד יגדל?
התקורה — יצירת מחרוזת ושדה נוסף בלוג; על רקע קריאות רשת מדובר בשברי אחוז. אנחנו מודדים לפני ואחרי על מערך פעולות בקרה ומציגים את ההפרש.
ומה אם רכיב צד שלישי אינו מעביר את המזהה?
הוא הופך לגבול המעקב: בכניסה מציבים מזהה משלנו ומסמנים את קרע השרשרת. זה כן יותר מאשר לחקות מעקב מקצה לקצה שאינו קיים.
נדבר על המעקב בשירותים שלכם
כדי שההערכה תהיה עניינית ולא "בעין", נדרש מערך מינימלי של נתוני קלט: לפיהם רואים היכן יהיה צורך להעביר את Correlation ID דרך מקומות ידניים, והיכן די בהגדרה סטנדרטית. תארו את המשימה וצרפו את מה שיש בהישג יד — נחזור עם תוכנית עבודה והערכה לפי שלבים.
- מפת השירותים של הלקוח: רשימת שירותים, מי קורא למי, אילו קשרים סינכרוניים ואילו עוברים דרך תורים וברוקר.
- נקודות כניסה של התעבורה: שער חיצוני, מאזן עומסים, שירותים בפריפריה — היכן מזהה הבקשה נוצר כעת והיכן הולך לאיבוד.
- העבודה הנוכחית עם לוגים: לאן נכתבים, האם קיים איסוף וחיפוש מרוכזים, איך נראית הרשומה ואילו שדות כבר קיימים.
- דרכי ההעברה בין שירותים: כותרות בקשה, הקשר בהודעות, משימות רקע, מתזמנים ומשימות לילה.
- שפות ופלטפורמות של השירותים: היכן יש ספריות משותפות והיכן יהיה צורך לכתוב מעטפת בנפרד לכל סטאק.
- דרישות לאחסון: תוחלת החיים של הלוגים, מי קורא את המעקב, האם נדרש מיסוך שדות רגישים.
- מסגרות ארגוניות: חלונות תחזוקה, סדר שחרורים, בעלי השירותים, מי מאשר שינויים.
בהמשך — סקירה קצרה של המפה והמגבלות שלכם, ולאחריה נתאם את פורמט ההטמעה: ספרייה אחידה או שער, היכן מקבעים את המזהה, כיצד מעבירים אותו הלאה, כיצד בודקים שהמעקב מקצה לקצה לא נקרע במעברים.
הצעד הבא פשוט: כתבו אילו שירותים אנחנו נוגעים בהם ומה כבר עובד בלוגים — ונחזור עם תוכנית עבודה, הרכב השינויים והערכה ברורה.







