בדף הזה מוסבר איך לקבל הודעות ולאשר את קבלתן באמצעות התכונה 'פעם אחת בדיוק' של Pub/Sub, שמאפשרת לעקוב אחרי עיבוד כפול של הודעות ולמנוע אותו. כשהתכונה מופעלת, Pub/Sub מספק את הסמנטיקה הבאה:
המנויים יכולים לדעת אם אישורי המסירה של ההודעות התקבלו.
לא מתבצעת מסירה חוזרת אחרי שההודעה מאושרת.
לא מתבצעת מסירה חוזרת בזמן שההודעה בהמתנה. הודעה נחשבת כהודעה שלא נשלחה עד שתאריך היעד לאישור שלה יפוג או עד שהיא תאושר.
במקרה של כמה מסירות תקפות, בגלל פקיעת תוקף של מועד אחרון לאישור או אישור שלילי שיזם הלקוח, אפשר להשתמש רק במזהה האישור האחרון כדי לאשר את ההודעה. כל הבקשות עם מזהה אישור קודם ייכשלו.
אם האפשרות 'עיבוד בדיוק פעם אחת' מופעלת, המנויים יכולים לוודא שההודעות יעובדו פעם אחת על ידי ביצוע ההנחיות הבאות:
לאשר את קבלת ההודעות לפני המועד האחרון לאישור.
שמירה של מידע על התקדמות העיבוד של הודעה עד לקבלת אישור מוצלח.
אפשר להשתמש במידע על התקדמות העיבוד של הודעה כדי למנוע כפילויות בעבודה כשאישור נכשל.
רק סוג המינוי pull תומך בשליחה בדיוק פעם אחת, כולל מנויים שמשתמשים ב-StreamingPull API. מינויים להעברת נתונים וייצוא לא תומכים במסירה של כל נתון בדיוק פעם אחת.
ב-Pub/Sub יש תמיכה במסירה בדיוק פעם אחת, באזור בענן, על סמך מזהה הודעה ייחודי שמוגדר ב-Pub/Sub.
גרסאות מומלצות של ספריות לקוח
- כדי לקבל את הביצועים הכי טובים, מומלץ להשתמש בגרסה האחרונה של ספריית הלקוח, Python v2.13.6 ואילך, Java v1.139.0 ואילך, PHP v1.39.0 ואילך, C# v3.2.0 ואילך, C++ v2.1.0, Go v1.25.1 ואילך, Node v3.2.0 ואילך ו-Ruby v2.12.1 ואילך.
העברה חוזרת לעומת כפילות
חשוב להבין את ההבדל בין מסירות חוזרות צפויות לבין מסירות חוזרות לא צפויות.
העברה חוזרת יכולה לקרות בגלל אישור שלילי של הודעה שהתקבל מלקוח, או כשהלקוח לא מאריך את המועד האחרון לאישור ההודעה לפני שהוא פג. מסירות חוזרות נחשבות תקינות והמערכת פועלת כמצופה.
כדי לפתור בעיות שקשורות למסירה חוזרת, אפשר לעיין במאמר טיפול בכפילויות.
שכפול מתרחש כששולחים מחדש הודעה אחרי אישור מוצלח או לפני שתוקף האישור פג.
הודעה שנשלחה מחדש שומרת על אותו מזהה הודעה בין ניסיונות השליחה מחדש.
במינויים שמופעלת בהם מסירה בדיוק פעם אחת, לא מתקבלות מסירות כפולות.
תמיכה באספקה בדיוק פעם אחת בספריות לקוח
לספריות לקוח נתמכות יש ממשק לאישור עם תגובה (לדוגמה: Go). אתם יכולים להשתמש בממשק הזה כדי לבדוק אם בקשת האישור הצליחה. אם בקשת האישור מצליחה, מובטח שהלקוחות לא יקבלו מסירה חוזרת. אם בקשת האישור נכשלת, הלקוחות יכולים לצפות למסירה חוזרת.
לקוחות יכולים גם להשתמש בספריות הלקוח הנתמכות בלי ממשק האישור. עם זאת, במקרים כאלה, כשלים באישור עלולים להוביל לשליחה חוזרת שקטה של הודעות.
לספריות לקוח נתמכות יש ממשקים להגדרת הזמן המינימלי להארכת השכירות (לדוגמה: Go). כדי למנוע מצבים שבהם תוקף האישור שקשור לרשת יפוג, צריך להגדיר את הערך של משך ההארכה המינימלי של השכירות למספר גבוה. הערך המקסימלי הוא 600 שניות.
אם אתם משתמשים בספריית הלקוח של Java ומאתחלים את המנוי באמצעות שיטת
setChannelProvider()של gRPC Channel בהתאמה אישית, מומלץ להגדיר גם אתmaxInboundMetadataSizeל-1MB לפחות כשיוצרים אתTransportChannelProvider. כדי להגדיר את זה, אפשר להשתמש בשיטהInstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize()או בשיטהManagedChannelBuilder.maxInboundMetadataSize().
ערכי ברירת המחדל והטווח של המשתנים שקשורים למסירה בדיוק פעם אחת, ושמות המשתנים, עשויים להיות שונים בספריות לקוח שונות. לדוגמה, בספריית הלקוח של Java, המשתנים הבאים שולטים במסירה של הודעה בדיוק פעם אחת.
| משתנה | תיאור | ערך |
|---|---|---|
setEnableExactlyOnceDelivery |
המתג מפעיל או משבית את האפשרות 'משלוח פעם אחת בלבד'. | true or false Default=false |
minDurationPerAckExtension |
הזמן המינימלי בשניות שמשמש להארכת המועד האחרון לאישור השינוי. | טווח=0 עד 600 ברירת מחדל=ללא |
maxDurationPerAckExtension |
פרק הזמן המקסימלי בשניות שבו אפשר להשתמש כדי להאריך את המועד האחרון לאישור שינוי. | הטווח הוא 0 עד 600. ברירת המחדל היא none. |
במקרה של מסירה בדיוק פעם אחת, הבקשה modifyAckDeadline או acknowledgment ל-Pub/Sub נכשלת כשמזהה האישור כבר פג. במקרים כאלה, השירות מחשיב את מזהה האישור שפג תוקפו כלא תקף, כי יכול להיות שמשלוח חדש יותר כבר בדרך. זהו עיצוב שנועד להבטיח מסירה של כל הודעה בדיוק פעם אחת. אחרי זה רואים שבקשות acknowledgment ו-ModifyAckDeadline מחזירות תגובה INVALID_ARGUMENT. כשמשביתים את האפשרות 'שליחה בדיוק פעם אחת', הבקשות האלה מחזירות OK במקרים של מזהי אישור שפג תוקפם.
כדי לוודא שלבקשות acknowledgment ו-ModifyAckDeadline יש מזהי אישור תקינים, כדאי להגדיר את הערך של minDurationPerAckExtension למספר גבוה.
שיקולים אזוריים
ההבטחה למסירה בדיוק פעם אחת חלה רק כשמנויים מתחברים לשירות באותו אזור. אם אפליקציית המנויים שלכם מפוזרת בכמה אזורים, יכול להיות שהודעות יישלחו כפליקטים, גם אם האפשרות 'שליחה בדיוק פעם אחת' מופעלת. בעלי תוכן דיגיטלי יכולים לשלוח הודעות לכל אזור, וההבטחה לשליחה בדיוק פעם אחת עדיין תקפה.
כשמריצים את האפליקציה ב- Cloud de Confiance, היא מתחברת כברירת מחדל לנקודת הקצה של Pub/Sub באותו אזור. לכן, הפעלת האפליקציה באזור אחד בתוך Cloud de Confianceבדרך כלל מבטיחה אינטראקציה עם אזור אחד.
כשמריצים את אפליקציית המינוי מחוץ לאזור אחד או בכמה אזורים, אפשר להבטיח שהחיבור יהיה לאזור אחד באמצעות נקודת קצה מיקומיות כשמגדירים את הלקוח של Pub/Sub. Cloud de Confianceכל נקודות הקצה של המיקום ב-Pub/Sub מצביעות על אזורים יחידים. מידע נוסף על נקודות קצה לפי מיקום זמין במאמר נקודות קצה ב-Pub/Sub. רשימה של כל נקודות הקצה למיקום ב-Pub/Sub מופיעה במאמר רשימה של נקודות קצה למיקום.
יצירת מינויים עם משלוח חד-פעמי בלבד
אפשר ליצור מינוי עם מסירה בדיוק פעם אחת באמצעות מסוף Cloud de Confiance , Google Cloud CLI, ספריית לקוח או Pub/Sub API.
מינוי שליפה
המסוף
כדי ליצור מינוי מסוג pull עם מסירה בדיוק פעם אחת, פועלים לפי השלבים הבאים:
נכנסים לדף Subscriptions במסוף Cloud de Confiance .
לוחצים על יצירת מינוי.
מזינים את מזהה המינוי.
בוחרים נושא מהתפריט הנפתח או יוצרים נושא חדש.
המינוי מקבל הודעות מהנושא.
בקטע Exactly once delivery (אספקה בדיוק פעם אחת), בוחרים באפשרות Enable exactly once delivery (הפעלת אספקה בדיוק פעם אחת).
לוחצים על יצירה.
gcloud
כדי ליצור מינוי מסוג pull עם מסירה בדיוק פעם אחת, משתמשים בפקודה gcloud pubsub subscriptions create עם הדגל --enable-exactly-once-delivery:
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --enable-exactly-once-delivery
מחליפים את מה שכתוב בשדות הבאים:
- SUBSCRIPTION_ID: המזהה של המינוי שרוצים ליצור
- TOPIC_ID: המזהה של הנושא לצירוף למינוי
REST
כדי ליצור מינוי עם מסירה בדיוק פעם אחת, משתמשים בשיטה projects.subscriptions.create.
PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID Authorization: Bearer $(gcloud auth print-access-token)
מחליפים את מה שכתוב בשדות הבאים:
- PROJECT_ID: מזהה הפרויקט שבו רוצים ליצור את המינוי
- SUBSCRIPTION_ID: המזהה של המינוי שרוצים ליצור
כדי ליצור מינוי שליפה עם מסירה בדיוק פעם אחת, מציינים את זה בגוף הבקשה:
{ "topic": "projects/PROJECT_ID/topics/TOPIC_ID", "enableExactlyOnceDelivery": true, }
מחליפים את מה שכתוב בשדות הבאים:
- PROJECT_ID: מזהה הפרויקט של הפרויקט עם הנושא
- TOPIC_ID: המזהה של הנושא לצירוף למינוי
C++
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של C++ במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף זמין במאמרי העזרה של Pub/Sub C++ API.
C#
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של C# במאמר הפעלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub C# API.
המשך
בדוגמה הבאה נעשה שימוש בגרסה הראשית של ספריית הלקוח Go Pub/Sub (v2). אם אתם עדיין משתמשים בספרייה v1, כדאי לעיין במדריך להעברה לגרסה v2. כדי לראות רשימה של דוגמאות קוד מגרסה 1, אפשר לעיין ב דוגמאות הקוד שהוצאו משימוש.
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Go במאמר מדריך למתחילים: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Go API.
Java
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Java במאמר התחלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Java API.
Python
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Python במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של ה-API בשפת Python של Pub/Sub.
Node.js
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במאמר הפעלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Node.js API.
Node.js
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במאמר הפעלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Node.js API.
Ruby
בדוגמה הבאה נעשה שימוש בספריית הלקוח של Ruby Pub/Sub בגרסה 3. אם אתם עדיין משתמשים בספרייה v2, כדאי לעיין במדריך להעברה לגרסה v3. כדי לראות רשימה של דוגמאות קוד של Ruby v2, אפשר לעיין ב דוגמאות הקוד שהוצאו משימוש.
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Ruby במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Ruby API.
PHP
לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של PHP במאמר התחלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub PHP API.
מעקב אחר מינויים עם מסירה בדיוק פעם אחת
המדד
subscription/exactly_once_warning_count
מתעד את מספר האירועים שיכולים להוביל למסירה חוזרת (תקינה או כפולה). המדד הזה סופר את מספר הפעמים שבהן Pub/Sub לא מצליח לעבד בקשות שמשויכות למזהי אישור (בקשת ModifyAckDeadline או acknowledgment). הסיבות לכשל יכולות להיות קשורות לשרת או ללקוח. לדוגמה, אם שכבת ההתמדה שמשמשת לשמירת פרטי המסירה בדיוק פעם אחת לא זמינה, זה יהיה אירוע מבוסס-שרת. אם הלקוח מנסה לאשר קבלת הודעה עם מזהה אישור קבלה לא תקין, זה יהיה אירוע מבוסס-לקוח.
הסבר על המדד
subscription/exactly_once_warning_count מתעד אירועים שעשויים להוביל או לא להוביל למסירות חוזרות בפועל, ויכול להיות שיהיו בו הרבה נתונים לא רלוונטיים בהתאם להתנהגות הלקוח. לדוגמה: בקשות חוזרות מסוג acknowledgment או ModifyAckDeadline עם מזהי אישור לא תקינים מגדילות את המדד שוב ושוב.
המדדים הבאים יכולים לעזור לכם להבין את התנהגות הלקוח:
subscription/expired_ack_deadlines_countהמדד הזה מציג את מספר הפעמים שפג התוקף של מזהה אישור. תוקף מזהה האישור פג, ולכן בקשותModifyAckDeadlineוacknowledgmentנכשלות.אפשר להשתמש במדד
service.serviceruntime.googleapis.com/api/request_countכדי לתעד כשלים בבקשות שלModifyAckDeadlineאוacknowledgmentבמקרים שבהם הבקשות מגיעות אל Cloud de Confiance by S3NS אבל לא מגיעות אל Pub/Sub. יש כשלים שהמדד הזה לא יתעד – למשל, כשלקוחות מנותקים מ- Cloud de Confiance by S3NS.
ברוב המקרים של אירועי כשל שאפשר לנסות שוב, ספריות לקוח נתמכות מנסות לשלוח את הבקשה מחדש באופן אוטומטי.
מכסות
מינויים עם מסירה של כל הודעה בדיוק פעם אחת כפופים לדרישות נוספות של מכסת השימוש. המכסות האלה נאכפות על:
- מספר ההודעות שנצרכו מהמינויים עם האפשרות 'מסירה בדיוק פעם אחת' מופעלת לכל אזור.
- מספר ההודעות שאושרה קבלתן או שהמועד האחרון שלהן הוארך כשמשתמשים במינויים עם שליחה חד-פעמית בדיוק שמופעלת לכל אזור.
מידע נוסף על המכסות האלה זמין בטבלה שבנושא מכסות.
משלוח בדיוק פעם אחת ומינויים מסודרים
ב-Pub/Sub יש תמיכה באספקה של הודעה אחת בלבד באמצעות אספקה מסודרת.
כשמשתמשים בהזמנה עם מסירה בדיוק פעם אחת, מערכת Pub/Sub מצפה לאישורים לפי הסדר. אם האישורים לא מגיעים לפי הסדר, השירות דוחה את הבקשות עם שגיאות זמניות. אם המועד האחרון לאישור יחלוף לפני אישור מסירה מסודר, הלקוח יקבל מסירה חוזרת של ההודעה. לכן, כשמשתמשים בהזמנה עם מסירה בדיוק פעם אחת, קצב העברת הנתונים של הלקוח מוגבל לסדר גודל של אלף הודעות בשנייה.
שליחת הודעות למינויים בדיוק פעם אחת
ב-Pub/Sub יש תמיכה בשליחה של הודעה אחת בלבד רק במינויי pull.
לקוחות שצורכים הודעות מהמינויים לשליחת נתונים (push) מאשרים את ההודעות על ידי שליחת תגובה מוצלחת לבקשות השליחה. עם זאת, הלקוחות לא יודעים אם המינוי ל-Pub/Sub קיבל את התגובה ועיבד אותה. זה שונה ממינויים מסוג pull, שבהם בקשות אישור נשלחות על ידי הלקוחות והמינוי ל-Pub/Sub מגיב אם הבקשה עובדה בהצלחה. לכן, הסמנטיקה של מסירה בדיוק פעם אחת לא מתאימה למינויים מסוג push.
חשוב לדעת
אם לא מציינים את תאריך היעד לאישור בזמן יצירת המינוי, מינויים עם משלוח של כל הודעה בדיוק פעם אחת יקבלו כברירת מחדל תאריך יעד לאישור של 60 שניות.
הארכת ברירת המחדל של מועדי האישור מועילה למניעת מסירה חוזרת שנגרמת על ידי אירועים ברשת. ספריות לקוח נתמכות לא משתמשות במועד האחרון לתגובה על מינוי שמוגדר כברירת מחדל.
במינויים עם אספקה בדיוק פעם אחת, זמן האחזור מפרסום להרשמה ארוך משמעותית בהשוואה למינויים רגילים.
אם אתם צריכים תפוקה גבוהה, לקוחות המסירה שלכם בדיוק פעם אחת צריכים להשתמש גם בשליפה של נתונים בסטרימינג.
יכול להיות שמינוי יקבל כמה עותקים של אותה הודעה בגלל כפילויות בצד הפרסום, גם אם מופעלת מסירה בדיוק פעם אחת. כפילויות בצד הפרסום יכולות לקרות בגלל ניסיונות חוזרים לפרסום ייחודי על ידי לקוח הפרסום או שירות Pub/Sub. פרסומים ייחודיים רבים על ידי לקוח הפרסום, במהלך ניסיונות חוזרים, מובילים למסירה חוזרת עם מזהי הודעות שונים. פרסום ייחודי כמה פעמים על ידי שירות Pub/Sub, בתגובה לבקשת פרסום של לקוח, מוביל למסירה חוזרת עם אותם מזהי הודעות.
אפשר לנסות שוב פעולות שנכשלו ב-
subscription/exactly_once_warning_count, וספריות הלקוח הנתמכות מנסות שוב את הפעולות האלה באופן אוטומטי. עם זאת, אי אפשר לנסות שוב שליחה של הודעות שקשורות למזהי אישור לא תקינים.