הגדרת Google Cloud Pub/Sub: תור מכתבים מתים, ניהול הרשאות, ניטור עבור צוותי פיתוח ותפעול

אובדן אירועים בזרימה עולה יותר ממה שנדמה: החישובים לא מסתדרים, וצריך לטפל בכך ידנית. אנו מגדירים Google Pub/Sub מקצה לקצה — מתכננים מנויים וניסיונות חוזרים, מפרידים הרשאות ומחברים ניטור. אתם מקבלים תרשים זרימות ונהלים שלפיהם המערכת פועלת באופן צפוי.

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

מדוע Google Pub/Sub מאבד הודעות בעומס שיא

אובדן הודעות לעתים רחוקות נראה כשגיאה בלוגים — לעתים קרובות יותר זה שקט: המטפל עובד, המדדים יציבים, אך חלק מהנתונים פשוט לא מגיע. המנוי שומר את ההודעה לזמן מוגבל ואינו ממתין ללא הגבלה: כל מה שלא אושר בזמן נמחק ללא החזרה לתור.

צוואר הבקבוק הראשון — הצפת המנוי. בעומס שיא הפרסום מקדים את העיבוד: הודעות לא מאושרות וחזרות מצטברות, מונה הממתינים גדל, והמטפל מקבל יותר ממה שהוא מסוגל לקלוט. הודעות אינן מונחות בתור לנצח — זנב הפיק נדחק החוצה לפני שמגיעים אליו.

השני — פסק זמן אישור. המטפל לוקח הודעה, יוצא לקריאה חיצונית או בקשה כבדה ולא מספיק לאשר אותה בחלון שהוקצב. השירות מחשיב את המסירה כלא מוצלחת ושולח עותק: הכפילויות ומונה המסירות גדלים, ובהיעדר מדיניות ניסיונות חוזרים ההודעה עוברת לתור הודעות שלא נמסרו או נמחקת בשקט.

התרחיש השלישי — מטפלים 'תקועים': התהליך חי, המדדים תקינים, אך אישור אינו נשלח — ההקשר אבד, הזרם חסום, הקונטיינר יוצא לאתחול מחדש. ההודעה מסתובבת במעגל עד שפג תוקף האחסון, ואובדת בדיוק במקום שבו היה צורך באבחון.

כל שלושת התרחישים מתכנסים לנקודה אחת — תצורת המנוי, ההודעות שלא נמסרו והרשאות הגישה אליהן. אנו מנתחים היכן בדיוק נקרע הזרם וכיצד סוגרים זאת.

אפקט מדיד: פחות אובדנים, כפילויות והשבתות

הגדרת המנוי משנה את מה שנראה במדדים. לפני כן, כשל של מטפל נראה כמו שקט: ההודעה נמסרה, אושרה, המטפל קרס — והאירוע אינו קיים לא במערכת ולא בתור. לאחר ההגדרה, כל מה שלא עבר עיבוד במספר הניסיונות שהוגדר עובר ל-dead-letter: הם נשארים בתור הטיפול ולא נעלמים.

כפילויות — סעיף ההפסדים השני. חלון אישור מורחב יחד עם אידמפוטנטיות לפי מפתח האירוע מסירים עיבוד חוזר במקום שבו אינו נחוץ, והחזרות שנותרו הופכות לבטוחות: מסירה חוזרת אינה יוצרת רשומה שנייה ואינה מבצעת חיוב שני. היקף העיבוד החוזר יורד, מכיוון שחלק מהכשלים נסגרים בצד המנוי.

האפקט השלישי — זמן ההתאוששות. התקלה מתגלה לא לפי פנייה של לקוח, אלא לפי התראה על גיל ההודעה הלא מאושרת הוותיקה ביותר ועל גידול ב-dead-letter: התורן רואה את הבעיה בהתחלה, לא בסוף. החזרה לעבודה — החלפת המנוי למטפל גיבוי, זה עניין של דקות, לא שעות.

מחלקה שלמה של תקלות נעלמת: 'אובדן אירוע שקט', 'עיבוד כפול', 'התור גדל יממה ואף אחד לא שם לב'. נראות הזרם נבנית על שלושה אותות — גיל ההודעות הלא מאושרות, מספר המסירות להודעה, נפח ה-dead-letter — וכל אחד מהם קשור לפעולה ספציפית של התורן.

אנו עובדים בתשתית Google Cloud Pub/Sub: כללי הניסיונות החוזרים, הרשאות הגישה וספי ההתראות מוגדרים באופן הצהרתי ומנוהלים בגרסאות יחד עם קוד השירות.

מצבי Google Pub/Sub: מנויים, אישורים, ניסיונות חוזרים

ב-Google Pub/Sub מצב המסירה נראה כפרט שולי כל עוד הזרם אחד. ברגע שיש כמה צרכנים, הוא קובע אילו כשלים תקבלו: מנוי דחיפה מגיע לכתובת שלכם ודורש תגובה מהירה, מנוי משיכה — לוקח הודעות בעצמו, ולכן הקצב, גודל האצווה וחלון העיבוד נבחרים בהתאם לעומס.

סדר ואישור נפתרים בנפרד. מפתח סדר קושר הודעות לתור אחד — הסדר נשמר בתוך המפתח, אך המקבילות יורדת. אישור עיבוד מאריך את החלון: אם הצרכן לא הספיק — ההודעה תחזור למסירה, ולאחר מספר ניסיונות נתון תעבור לתור ההודעות שלא נמסרו.

אפשרות מתי מתאימה מגבלות
מנוי משיכה שירותים עצמאיים, שליפה באצוות, קצב גבוה נדרש לולאת polling ולוגיקת אישורים משל עצמך
מנוי דחיפה אירועים לשירותים חיצוניים, פונקציות ללא צרכן קבוע נדרשת כתובת נגישה ותגובה מהירה, בחלון האישור אינך שולט
עיבוד זרימה זרם רציף עם השהיה מינימלית חיבור קבוע, קשה יותר להשהות ולבטל
מספר מנויים זרם אחד לצוותים ותרחישים שונים מדיניות הניסיונות החוזרים וההודעות שלא נמסרו שונות לכל אחד, כפילויות נבלמות על ידי אידמפוטנטיות
מפתח סדר חשוב סדר בתוך موجودות אחת פחות מקבילות, מפתח חם הופך לצוואר בקבוק

מצב המסירה קובע את סוג הכשלים שתנתחו לאחר מכן בתורנות. להלן — כיצד אנו מחברים מנויים, הרשאות וניטור לסכימה ניהולית אחת.

סדר היישום: מביקורת זרמים ועד מסירת נהלים

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

  1. ביקורת זרמים. מלאי של טופיקים ומנויים ב-Pub/Sub: מי מפרסם, מי קורא, מהי ההשהיה המותרת, היכן שגיאות אינן עולות במדדים.
  2. תכנון סכימה. מפרקים זרמים לפי קריטיות, קובעים טופולוגיית טופיקים ומנויים, זמן אחסון וטופיק dead-letter נפרד להודעות שלא עובדו.
  3. הגדרת ניסיונות חוזרים. מדיניות ניסיונות חוזרים עם השהיה בין ניסיונות, מספר מסירות לשליחה ל-dead-letter, התנהגות בעת ביטול אישור: הודעה כושלת מוסטת הצידה, והזרם ממשיך לזרום.
  4. הרשאות. חשבונות שירות ותפקידים לפי סט ההרשאות המינימלי הנדרש: מנוי אינו מפרסם, אוסף מדדים אינו קורא גופי הודעות.
  5. בדיקת כשלים. מנתקים מנוי, מבטלים הרשאות, שוברים מטפל — בוחנים מה קורה לתור, האם הניסיונות החוזרים מופעלים, האם התקלה נראית בניטור.
  6. בדיקת עומס. מריצים פרופיל קרוב לשיא: כמה מחזיק הזרם ללא גידול בהשהיה, כיצד גדל נפח ההודעות שלא עובדו, באיזה קצב מתחילות חזרות המוניות.
  7. ניטור ומסירת נהלים. התראות על גיל ההודעה הלא מאושרת הוותיקה ביותר, שיעור ההודעות ב-dead-letter ושגיאות פרסום; הוראות למשמרת תורנית וסדר טיפול בתקלות.

ערכת מסירה: סכימות זרמים, מדיניות גישה, נהלים

ערכת המסירה אינה מצגת, אלא תיעוד עבודה שלפיו המשמרת התורנית והמהנדסים שלכם פועלים בלעדינו. את כל הגדרות Pub/Sub אנו מתעדים במאגר שלכם: סכימות, מדיניות ונהלים מנוהלים בגרסאות, שינויים עוברים סקירה, ואינם חיים בזיכרונו של מישהו או בהתכתבות.

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

מקרה בוחן: אובדן אירועים במערך סליקה — דינמיקה לפני ואחרי

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

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

הגישה של השירותים לטופיקים ולמנויים הופרדה לתפקידים נפרדים — חשבון הטוען אינו יכול עוד לקרוא ולמחוק מנויים של אחרים.

דינמיקה לפי מדדים

מדד לפני העבודה אחרי תקופת ניטור
שיעור אירועי סליקה שאבדו כ-2% ביום מתחת ל-0.05%
גילוי כשל עיבוד בהתאמה של הבוקר לפי התראה, דקות
טיפול ידני בתקלה ניתוח כל אצוות הלוגים לפי מזהה הודעה
חזרה לסכימת העיבוד הקודמת אתחול המערך החלפת גרסת המנוי

המערך פועל על Google Cloud Pub/Sub, והמפתח התברר לא כהפעלה עצמה של ניסיונות חוזרים, אלא כהתאמת חלון האחסון של הודעות שלא נמסרו לזמן התגובה של המשמרת התורנית: אם הוא קצר יותר, הודעות אובדות כבר ביציאה מהתור. בתום חודש ניטור, אף יום סליקה לא נסגר בפער הדורש תיקון ידני של רשומות.

במה נבדלת הודעה שלא נמסרה מהודעה חוזרת

הגבול עובר לא לפי עצם העיבוד הכושל, אלא לפי מונה הניסיונות. כל עוד מכסת הניסיונות לא מוצתה, ההודעה נשארת במנוי וחוזרת למנוי בשנית — זהו מצב רגיל של מסירה חוזרת, לא שגיאה.

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

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

כל עוד השגיאה זמנית — אי-זמינות של תלות, עיכוב ברשת, פיק בעומס — כמה מחזורים מספיקים, וההודעה יוצאת לעבודה.

הודעות מורעלות מתנהגות אחרת: המטפל קורס בכל חזרה מאותה סיבה בדיוק. סכימה לא תקינה, הפניה לאובייקט שנמחק, הפרת אינווריאנטה של הנתונים — כשלים כאלה דטרמיניסטיים, ואין טעם להרבות ניסיונות. הסימן הוא אחד בדיוק: אותו סוג שגיאה בניסיונות שונים.

כאשר המונה מגיע למכסה, הפלטפורמה חייבת לבחור: למחוק את ההודעה או לשלוח אותה לתור טיפול נפרד. תור הטיפול אינו ארכיון ואינו מזבלה, אלא מקום העבודה של המהנדס התורן: רק מה שדורש החלטה ידנית או תיקון נתונים מגיע לשם. אם לא תקים אותו, הפלטפורמה תזרוק את ההודעה, ולא יישארו עקבות.

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

ספקות טכניים: השהיות, כפילויות, חלוקת הרשאות

השהיות מסירה אינן כשל, אלא תכונה של חילופין אסינכרוניים. ב-Google Cloud Pub/Sub המסלול מהפרסום לעיבוד תלוי בגודל האצווה, בחלון האישור ובמהירות המטפל עצמו. אם המנוי מגיב זמן רב יותר ממה שחלון האישור פג, הברוקר מחשיב את ההודעה כלא מעובדת ומוסר אותה שוב — כך נוצרות כפילויות.

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

תולים התראות על עומק התור וגיל ההודעה הלא מאושרת הוותיקה ביותר, ולא על מונה שגיאות בלוגים: בדיוק המדדים האלה מראים את צריכת המשאבים ואת הפיגור בעיבוד.

הודעות מגיעות שוב — האם זו שגיאת הגדרה?

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

כיצד להבין שהבעיה בהרשאות ולא בקוד?

סירוב פרסום ושליפה ריקה של מנוי נראים דומים. אנו מפרידים ביניהם לפי יומן הגישה: תפקידים נפרדים לטופיק ולמנוי מראים מיד היכן בדיוק הסירוב. גישה ניתנת לפי המינימום הנדרש, ולכן אין צורך להרחיב אותה לצורך דיבוג.

האם ההגדרות משפיעות על צריכת המשאבים?

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

נדון בסכימת חילופי ההודעות ובנקודות הכשל שלכם

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

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

נדון במשימה בפורמט של ניתוח: נעבור על סכימת החילופין, נסמן צווארי בקבוק ונקודות כשל, נקבע מה עושים קודם כל. תארו את המצב שלכם — נחזור עם הערכה ותוכנית עבודה ובה שלבים, תחומי אחריות ודרך לבדיקת התוצאה.