אסטרטגיה של ניסיון חוזר

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

סקירה כללית על ניסיונות חוזרים

הגורמים הבאים קובעים אם בטוח לבצע ניסיון חוזר של בקשה:

  • התגובה שאתם מקבלים מהבקשה.

  • האידמפוטנטיות של הבקשה.

תשובה

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

  • קודי תגובה של HTTP: 408, 429 ו-5xx.
  • זמנים קצובים לתפוגה של שקעים וניתוקים של TCP.

מידע נוסף מופיע במאמרים על קודי הסטטוס וקודי השגיאה של JSON ושל XML.

האידמפוטנטיות

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

הדוגמאות הבאות הן מציגות תנאים שגורמים לפעולה להיות אידמפוטנטית:

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

  • הפעולה מצליחה רק פעם אחת.

  • לפעולה אין השפעה גלויה על המצב של משאב היעד.

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

אידמפוטנטיות מותנית

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

אידמפוטנטיות של פעולות

בטבלה הבאה מפורטות הפעולות של Cloud Storage לפי קטגוריות של אידמפוטנטיות.

האידמפוטנטיות פעולות
תמיד אידמפוטנטית
  • כל הבקשות של get ו-list
  • הוספה או מחיקה של קטגוריות
  • בדיקת מדיניות והרשאות IAM לקטגוריות
  • נעילה של מדיניות שמירת נתונים
  • מחיקת מפתח HMAC או התראת Pub/Sub
אידמפוטנטית באופן מותנה
  • בקשות update/patch לקטגוריות עם IfMetagenerationMatch1 או etag1 כתנאי מוקדם של HTTP
  • בקשות update/patch לאובייקטים עם IfMetagenerationMatch1 או etag1 כתנאי מוקדם של HTTP
  • הגדרה של מדיניות IAM בקטגוריה עם etag1 כתנאי מוקדם של HTTP או בגוף המשאב
  • עדכון מפתח HMAC עם etag1 כתנאי מוקדם של HTTP או בגוף המשאב
  • הוספה, העתקה, הרכבה או שכתוב של אובייקטים עם ifGenerationMatch1
  • מחיקת אובייקט עם ifGenerationMatch1 (או באמצעות מספר גנרציה לגרסאות של אובייקטים)
אף פעם לא אידמפוטנטית
  • יצירה של מפתח HMAC
  • יצירה של התראת Pub/Sub
  • יצירה, מחיקה או שליחה של בקשות update/patch לרשימות ACL של קטגוריות ואובייקטים או לרשימות ACL שמשמשות כברירת המחדל של אובייקטים.

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

איך הכלים של Cloud Storage מטמיעים אסטרטגיות של ניסיונות חוזרים

המסוף

מסוף Google Cloud שולח בקשות ל-Cloud Storage בשמכם ומטפל בכל השהיה לפני ניסיון חוזר (backoff) שנדרשת.

שורת הפקודה

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

  • פרטי הכניסה לא תקינים או שההרשאות לא מספיקות.

  • הרשת אינה נגישה בגלל בעיה בהגדרה של שרת proxy.

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

ספריות לקוח

C++‎

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

  • 408 Request Timeout
  • 429 Too Many Requests
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout

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

הגדרה ערך ברירת המחדל
ניסיון חוזר אוטומטי True
משך הזמן המקסימלי לביצוע ניסיון חוזר של בקשה ‫15 דקות
זמן המתנה (backoff) ראשוני שנייה אחת
מכפיל של זמן המתנה לכל איטרציה 2
זמן המתנה מקסימלי ‫5 דקות

כברירת מחדל, ספריית C++‎ מבצעת ניסיון חוזר של כל הפעולות עם שגיאות שמאפשרות ניסיון חוזר, גם כאלה שהן אף פעם לא אידמפוטנטיות ושהן יכולות למחוק או ליצור משאבים מרובים כשהן מבוצעות שוב ללא שגיאות. כדי לבצע ניסיון חוזר רק של פעולות אידמפוטנטיות, אתם צריכים להשתמש במחלקה google::cloud::storage::StrictIdempotencyPolicy.

C#‎

ספריית הלקוח C#‎ משתמשת בהשהיה מעריכית לפני ניסיון חוזר (exponential backoff) כברירת מחדל.

Go

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

  • שגיאות התחברות:
    • ‫io.ErrUnexpectedEOF: ייתכן בגלל בעיות זמניות ברשת.
    • ‫url.Error עם connection refused: ייתכן בגלל בעיות זמניות ברשת.
    • ‫url.Error עם connection reset by peer: המשמעות היא ש- Google Cloud איפס את החיבור.
    • ‫net.ErrClosed: המשמעות היא ש- Google Cloud סגר את החיבור.
  • קודי HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • שגיאות שמטמיעות את הממשק Temporary() ונותנות את הערך err.Temporary() == true
  • כל אחת מהשגיאות הקודמות שארוזה באמצעות Go 1.13 error wrapping

אפשר לקבוע את כל ההגדרות של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) בספרייה של Go. כברירת מחדל, הפעולות ב-Go משתמשות בהגדרות הבאות להשהיה מעריכית לפני ניסיון חוזר (ברירות המחדל נלקחות מ-gax):

הגדרה ערך ברירת המחדל (בשניות)
ניסיון חוזר אוטומטי ‫True אם הפעולה אידמפוטנטית
מספר ניסיונות מקסימלי אין מגבלה
השהיה ראשונית של ניסיון חוזר שנייה אחת
מכפיל ההשהיה של הניסיון החוזר 2.0
השהיה מקסימלית של הניסיון החוזר ‫30 שניות
הזמן הכולל הקצוב לתפוגה (מקטע של העלאה שניתן להמשיך) ‫32 שניות
הזמן הכולל הקצוב לתפוגה (כל הפעולות האחרות) אין מגבלה

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

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

  • ‫GenerationMatch או Generation

    • ביצוע ניסיון חוזר הוא בטוח אם מחילים על הקריאה את התנאי המוקדם GenerationMatch, או אם הוגדר ObjectHandle.Generation.
  • MetagenerationMatch

    • ביצוע ניסיון חוזר הוא בטוח אם מחילים על הקריאה את התנאי המוקדם MetagenerationMatch.
  • Etag

    • ביצוע ניסיון חוזר הוא בטוח אם ה-method מוסיפה etag לגוף הבקשה של JSON. בשימוש רק ב-HMACKeyHandle.Update כשמוגדר HmacKeyMetadata.Etag.

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

Java

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

  • שגיאות התחברות:
    • ‫Connection reset by peer: המשמעות היא ש- Google Cloud איפס את החיבור.
    • ‫Unexpected connection closure: המשמעות היא ש- Google Cloud סגר את החיבור.
  • קודי HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

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

הגדרה ערך ברירת המחדל (בשניות)
ניסיון חוזר אוטומטי ‫True אם הפעולה אידמפוטנטית
מספר ניסיונות מקסימלי 6
השהיה ראשונית של ניסיון חוזר שנייה אחת
מכפיל ההשהיה של הניסיון החוזר 2.0
השהיה מקסימלית של הניסיון החוזר ‫32 שניות
הזמן הקצוב הכולל לתפוגה ‫50 שניות
הזמן הקצוב הראשוני לתפוגת RPC ‫50 שניות
מכפיל הזמן הקצוב לתפוגת RPC 1.0
הזמן הקצוב המרבי לתפוגת RPC ‫50 שניות
הזמן הקצוב לתפוגת החיבור ‫20 שניות
הזמן הקצוב לתפוגת הקריאה ‫20 שניות

למידע נוסף על ההגדרות, עיינו במאמרי העזרה של Java ל-RetrySettings.Builder ול-HttpTransportOptions.Builder.

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

  • ‫ifGenerationMatch או generation

    • אפשר לבצע ניסיון חוזר באופן בטוח אם ifGenerationMatch או generation מועברים כאפשרות ל-method.
  • ifMetagenerationMatch

    • אפשר לבצע ניסיון חוזר באופן בטוח אם ifMetagenerationMatch מועבר כאפשרות.

כברירת המחדל, StorageOptions.setStorageRetryStrategy מוגדר כ-StorageRetryStrategy#getDefaultStorageRetryStrategy. לדוגמאות איך לשנות את התנהגות ברירת המחדל של ניסיונות חוזרים, אפשר לעיין בחלק התאמה אישית של ניסיונות חוזרים.

Node.js

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

  • שגיאות התחברות:
    • ‫EAI_again: זוהי שגיאה בחיפוש DNS. למידע נוסף, עיינו במאמרי העזרה בנושא getaddrinfo.
    • ‫Connection reset by peer: המשמעות היא ש- Google Cloud איפס את החיבור.
    • ‫Unexpected connection closure: המשמעות היא ש- Google Cloud סגר את החיבור.
  • קודי HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

אפשר לקבוע את כל ההגדרות של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) בספריית Node.js. כברירת מחדל, פעולות באמצעות Node.js משתמשות בהגדרות הבאות להשהיה מעריכית לפני ניסיון חוזר:

הגדרה ערך ברירת המחדל (בשניות)
ניסיון חוזר אוטומטי ‫True אם הפעולה אידמפוטנטית
המספר המרבי של ניסיונות חוזרים 3
זמן המתנה ראשוני שנייה אחת
מכפיל של זמן המתנה לכל איטרציה 2
זמן המתנה מקסימלי ‫64 שניות
ברירת המחדל של מועד אחרון ‫600 שניות

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

  • ‫ifGenerationMatch או generation

    • אפשר לבצע ניסיון חוזר באופן בטוח אם ifGenerationMatch או generation מועברים כאפשרות ל-method. לעיתים קרובות, ה-methods מקבלות רק אחד משני הפרמטרים האלה.
  • ifMetagenerationMatch

    • אפשר לבצע ניסיון חוזר באופן בטוח אם ifMetagenerationMatch מועבר כאפשרות.

כברירת המחדל, retryOptions.idempotencyStrategy מוגדר כ-IdempotencyStrategy.RetryConditional. לדוגמאות איך לשנות את התנהגות ברירת המחדל של ניסיונות חוזרים, אפשר לעיין בחלק התאמה אישית של ניסיונות חוזרים.

PHP

ספריית הלקוח של PHP משתמשת בהשהיה מעריכית לפני ניסיון חוזר (exponential backoff) כברירת מחדל.

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

  • שגיאות התחברות:
    • ‫connetion-refused: יכול להיות בגלל בעיות זמניות ברשת.
    • ‫connection-reset: המשמעות היא ש- Google Cloud איפס את החיבור.
  • קודי HTTP:
    • ‫200: במקרים של הורדה חלקית
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

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

הגדרה ערך ברירת המחדל (בשניות)
ניסיון חוזר אוטומטי ‫True אם הפעולה אידמפוטנטית
השהיה ראשונית של ניסיון חוזר שנייה אחת
מכפיל ההשהיה של הניסיון החוזר 2.0
השהיה מקסימלית של הניסיון החוזר ‫60 שניות
משך הבקשה הסתיים ‫0 עם REST, ‏60 עם gRPC
מספר ברירת המחדל של ניסיונות חוזרים 3

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

  • ‫ifGenerationMatch או generation

    • אפשר לבצע ניסיון חוזר באופן בטוח אם ifGenerationMatch או generation מועברים כאפשרות ל-method. לעיתים קרובות, ה-methods מקבלות רק אחד משני הפרמטרים האלה.
  • ifMetagenerationMatch

    • אפשר לבצע ניסיון חוזר באופן בטוח אם ifMetagenerationMatch מועבר כאפשרות.

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

Python

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

  • שגיאות התחברות:
    • requests.exceptions.ConnectionError
    • ‫requests.exceptions.ChunkedEncodingError (רק לפעולות שבהן אפשר לאחזר או לשלוח נתוני מטען ייעודי (payload) לאובייקטים, כמו העלאות והורדות)
    • ConnectionError
    • http.client.ResponseNotReady
    • urllib3.exceptions.TimeoutError
  • קודי HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

פעולות באמצעות Python משתמשות בהגדרות ברירת המחדל הבאות להשהיה מעריכית לפני ניסיון חוזר (exponential backoff):

הגדרה ערך ברירת המחדל (בשניות)
ניסיון חוזר אוטומטי ‫True אם הפעולה אידמפוטנטית
זמן המתנה ראשוני 1
מכפיל של זמן המתנה לכל איטרציה 2
זמן המתנה מקסימלי 60
ברירת המחדל של מועד אחרון 120

בנוסף לפעולות ב-Cloud Storage שהן תמיד אידמפוטנטיות, ספריית הלקוח של Python מנסה שוב באופן אוטומטי את הפעולות Objects: insert,‏ Objects: delete ו-Objects: patch כברירת מחדל.

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

  • DEFAULT_RETRY_IF_GENERATION_SPECIFIED

    • אפשר לבצע ניסיון חוזר באופן בטוח אם מועברים generation או if_generation_match כארגומנט ל-method. לעיתים קרובות, ה-methods מקבלות רק אחד משני הפרמטרים האלה.
  • DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED

    • אפשר לבצע ניסיון חוזר באופן בטוח אם הועבר if_metageneration_match כארגומנט ל-method.
  • DEFAULT_RETRY_IF_ETAG_IN_JSON

    • ביצוע ניסיון חוזר הוא בטוח אם ה-method מוסיפה etag לגוף הבקשה של JSON. לגבי HMACKeyMetadata.update(), המשמעות היא שצריך להגדיר את ה-etag באובייקט HMACKeyMetadata עצמו. ל-method set_iam_policy() במחלקות אחרות, המשמעות היא שצריך להגדיר את ה-etag בארגומנט 'policy' שמועבר ל-method.

Ruby

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

  • שגיאות התחברות:
    • SocketError
    • HTTPClient::TimeoutError
    • Errno::ECONNREFUSED
    • HTTPClient::KeepAliveDisconnected
  • קודי HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 5xx Server Error

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

הגדרה ערך ברירת המחדל
ניסיון חוזר אוטומטי True
המספר המרבי של ניסיונות חוזרים 3
זמן המתנה ראשוני שנייה אחת
מכפיל של זמן המתנה לכל איטרציה 2
זמן המתנה מקסימלי ‫60 שניות
ברירת המחדל של מועד אחרון ‫900 שניות

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

  • ‫if_generation_match או generation

    • אפשר לבצע ניסיון חוזר באופן בטוח אם הפרמטר generation או if_generation_match מועבר כארגומנט ל-method. לעיתים קרובות, ה-methods מקבלות רק אחד משני הפרמטרים האלה.
  • if_metageneration_match

    • ביצוע ניסיון חוזר הוא בטוח אם הפרמטר if_metageneration_match מועבר בתור אפשרות.

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

ממשקי API בארכיטקטורת REST

כששולחים קריאה ישירה ל-API בפורמט JSON או ל-API בפורמט XML, אתם צריכים להשתמש באלגוריתם של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) כדי להטמיע את האסטרטגיה שלכם לביצוע ניסיונות חוזרים.

התאמה אישית של ניסיונות חוזרים

המסוף

אי אפשר להתאים אישית את ההתנהגות של הניסיונות החוזרים באמצעות מסוף Google Cloud .

שורת הפקודה

לפקודות gcloud storage אפשר לשלוט באסטרטגיית הניסיונות החוזרים על ידי יצירת תצורה בעלת שם, והגדרה של כל המאפיינים (properties) הבאים או של חלקם:

הגדרה ערך ברירת המחדל (בשניות)
base_retry_delay 1
exponential_sleep_multiplier 2
max_retries 32
max_retry_delay 32

אחרי זה מחילים את התצורה המוגדרת על כל פקודה בנפרד באמצעות הדגל --configuration בכל הפרויקט, או על כל הפקודות של Google Cloud CLI באמצעות הפקודה gcloud config set.

ספריות לקוח

C++‎

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

  • ‫google::cloud::storage::RetryPolicyOption: הספרייה מספקת את המחלקות google::cloud::storage::LimitedErrorCountRetryPolicy ו-google::cloud::storage::LimitedTimeRetryPolicy. אתם יכולים לספק מחלקה משלכם, שבה צריך להטמיע את הממשק של google::cloud::RetryPolicy.

  • ‫google::cloud::storage::BackoffPolicyOption: הספרייה מספקת את המחלקה google::cloud::storage::ExponentialBackoffPolicy. אתם יכולים לספק מחלקה משלכם, שבה צריך להטמיע את הממשק של google::cloud::storage::BackoffPolicy.

  • ‫google::cloud::storage::IdempotencyPolicyOption: הספרייה מספקת את המחלקות google::cloud::storage::StrictIdempotencyPolicy ו-google::cloud::storage::AlwaysRetryIdempotencyPolicy. אתם יכולים לספק מחלקה משלכם, שבה צריך להטמיע את הממשק של google::cloud::storage::IdempotencyPolicy.

מידע נוסף זמין במאמרי העזרה לספריית הלקוח של C++.

namespace gcs = ::google::cloud::storage;
// Create the client configuration:
auto options = google::cloud::Options{};
// Retries only idempotent operations.
options.set<gcs::IdempotencyPolicyOption>(
    gcs::StrictIdempotencyPolicy().clone());
// On error, it backs off for a random delay between [1, 3] seconds, then [3,
// 9] seconds, then [9, 27] seconds, etc. The backoff time never grows larger
// than 1 minute.
options.set<gcs::BackoffPolicyOption>(
    gcs::ExponentialBackoffPolicy(
        /*initial_delay=*/std::chrono::seconds(1),
        /*maximum_delay=*/std::chrono::minutes(1),
        /*scaling=*/3.0)
        .clone());
// Retries all operations for up to 5 minutes, including any backoff time.
options.set<gcs::RetryPolicyOption>(
    gcs::LimitedTimeRetryPolicy(std::chrono::minutes(5)).clone());
return gcs::Client(std::move(options));

C#‎

אי אפשר להתאים אישית את אסטרטגיית ברירת המחדל של הניסיונות החוזרים שבה משתמשת ספריית הלקוח C# ‎.

המשך

כשמאתחלים לקוח אחסון, תיקבע תצורת ברירת המחדל של הניסיונות החוזרים. אם לא משנים את הערכים, האפשרויות בתצורה מוגדרות לערכי ברירת המחדל. המשתמשים יכולים להגדיר התנהגות של ניסיונות חוזרים ששונה מברירת המחדל לקריאה לספרייה יחידה (באמצעות BucketHandle.Retryer ו-ObjectHandle.Retryer) או לכל הקריאות שנשלחות על ידי לקוח (באמצעות Client.SetRetry). כדי לשנות את ההתנהגות של ניסיונות חוזרים, צריך להעביר את האפשרויות הרלוונטיות של RetryOptions לאחת מה-methods הבאות.

דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
	"github.com/googleapis/gax-go/v2"
)

// configureRetries configures a custom retry strategy for a single API call.
func configureRetries(w io.Writer, bucket, object string) error {
	// bucket := "bucket-name"
	// object := "object-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

	// Configure retries for all operations using this ObjectHandle. Retries may
	// also be configured on the BucketHandle or Client types.
	o := client.Bucket(bucket).Object(object).Retryer(
		// Use WithBackoff to control the timing of the exponential backoff.
		storage.WithBackoff(gax.Backoff{
			// Set the initial retry delay to a maximum of 2 seconds. The length of
			// pauses between retries is subject to random jitter.
			Initial: 2 * time.Second,
			// Set the maximum retry delay to 60 seconds.
			Max: 60 * time.Second,
			// Set the backoff multiplier to 3.0.
			Multiplier: 3,
		}),
		// Use WithPolicy to customize retry so that all requests are retried even
		// if they are non-idempotent.
		storage.WithPolicy(storage.RetryAlways),
	)

	// Use context timeouts to set an overall deadline on the call, including all
	// potential retries.
	ctx, cancel := context.WithTimeout(ctx, 500*time.Second)
	defer cancel()

	// Delete an object using the specified retry policy.
	if err := o.Delete(ctx); err != nil {
		return fmt.Errorf("Object(%q).Delete: %w", object, err)
	}
	fmt.Fprintf(w, "Blob %v deleted with a customized retry strategy.\n", object)
	return nil
}

Java

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

הדוגמה הבאה מראה איך להתאים אישית את ההתנהגות של ניסיונות חוזרים:


import com.google.api.gax.retrying.RetrySettings;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.storage.StorageRetryStrategy;
import org.threeten.bp.Duration;

public final class ConfigureRetries {
  public static void main(String[] args) {
    String bucketName = "my-bucket";
    String blobName = "blob/to/delete";
    deleteBlob(bucketName, blobName);
  }

  static void deleteBlob(String bucketName, String blobName) {
    // Customize retry behavior
    RetrySettings retrySettings =
        StorageOptions.getDefaultRetrySettings().toBuilder()
            // Set the max number of attempts to 10 (initial attempt plus 9 retries)
            .setMaxAttempts(10)
            // Set the backoff multiplier to 3.0
            .setRetryDelayMultiplier(3.0)
            // Set the max duration of all attempts to 5 minutes
            .setTotalTimeout(Duration.ofMinutes(5))
            .build();

    StorageOptions alwaysRetryStorageOptions =
        StorageOptions.newBuilder()
            // Customize retry so all requests are retried even if they are non-idempotent.
            .setStorageRetryStrategy(StorageRetryStrategy.getUniformStorageRetryStrategy())
            // provide the previously configured retrySettings
            .setRetrySettings(retrySettings)
            .build();

    // Instantiate a client
    Storage storage = alwaysRetryStorageOptions.getService();

    // Delete the blob
    BlobId blobId = BlobId.of(bucketName, blobName);
    boolean success = storage.delete(blobId);

    System.out.printf(
        "Deletion of Blob %s completed %s.%n", blobId, success ? "successfully" : "unsuccessfully");
  }
}

Node.js

כשמאתחלים את Cloud Storage, מתבצע גם אתחול של קובץ התצורה retryOptions. אם לא משנים את הערכים, האפשרויות בתצורה מוגדרות לערכי ברירת המחדל. כדי לשנות את התנהגות ברירת המחדל של הניסיונות החוזרים, במהלך האתחול מעבירים את התצורה של הניסיונות החוזרים retryOptions ל-constructor של האחסון. ספריית הלקוח של Node.js יכולה להשתמש באופן אוטומטי באסטרטגיות השהיה לפני ניסיון חוזר (backoff) כדי לבצע ניסיון חוזר של בקשות עם הפרמטר autoRetry.

דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of your GCS file
// const fileName = 'your-file-name';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage({
  retryOptions: {
    // If this is false, requests will not retry and the parameters
    // below will not affect retry behavior.
    autoRetry: true,
    // The multiplier by which to increase the delay time between the
    // completion of failed requests, and the initiation of the subsequent
    // retrying request.
    retryDelayMultiplier: 3,
    // The total time between an initial request getting sent and its timeout.
    // After timeout, an error will be returned regardless of any retry attempts
    // made during this time period.
    totalTimeout: 500,
    // The maximum delay time between requests. When this value is reached,
    // retryDelayMultiplier will no longer be used to increase delay time.
    maxRetryDelay: 60,
    // The maximum number of automatic retries attempted before returning
    // the error.
    maxRetries: 5,
    // Will respect other retry settings and attempt to always retry
    // conditionally idempotent operations, regardless of precondition
    idempotencyStrategy: IdempotencyStrategy.RetryAlways,
  },
});
console.log(
  'Functions are customized to be retried according to the following parameters:'
);
console.log(`Auto Retry: ${storage.retryOptions.autoRetry}`);
console.log(
  `Retry delay multiplier: ${storage.retryOptions.retryDelayMultiplier}`
);
console.log(`Total timeout: ${storage.retryOptions.totalTimeout}`);
console.log(`Maximum retry delay: ${storage.retryOptions.maxRetryDelay}`);
console.log(`Maximum retries: ${storage.retryOptions.maxRetries}`);
console.log(
  `Idempotency strategy: ${storage.retryOptions.idempotencyStrategy}`
);

async function deleteFileWithCustomizedRetrySetting() {
  await storage.bucket(bucketName).file(fileName).delete();
  console.log(`File ${fileName} deleted with a customized retry strategy.`);
}

deleteFileWithCustomizedRetrySetting();

PHP

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

דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.

use Google\Cloud\Storage\StorageClient;

/**
 * Configures retries with customizations.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 */
function configure_retries(string $bucketName): void
{
    $storage = new StorageClient([
        // The maximum number of automatic retries attempted before returning
        // the error.
        // Default: 3
        'retries' => 10,

        // Exponential backoff settings
        // Retry strategy to signify that we never want to retry an operation
        // even if the error is retryable.
        // Default: StorageClient::RETRY_IDEMPOTENT
        'retryStrategy' => StorageClient::RETRY_ALWAYS,

        // Executes a delay
        // Defaults to utilizing `usleep`.
        // Function signature should match: `function (int $delay) : void`.
        // This function is mostly used internally, so the tests don't wait
        // the time of the delay to run.
        'restDelayFunction' => function ($delay) {
            usleep($delay);
        },

        // Sets the conditions for determining how long to wait between attempts to retry.
        // Function signature should match: `function (int $attempt) : int`.
        // Allows to change the initial retry delay, retry delay multiplier and maximum retry delay.
        'restCalcDelayFunction' => fn ($attempt) => ($attempt + 1) * 100,

        // Sets the conditions for whether or not a request should attempt to retry.
        // Function signature should match: `function (\Exception $ex) : bool`.
        'restRetryFunction' => function (\Exception $e) {
            // Custom logic: ex. only retry if the error code is 404.
            return $e->getCode() === 404;
        },

        // Runs after the restRetryFunction. This might be used to simply consume the
        // exception and $arguments b/w retries. This returns the new $arguments thus allowing
        // modification on demand for $arguments. For ex: changing the headers in b/w retries.
        'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) {
            // logic
        },
    ]);
    $bucket = $storage->bucket($bucketName);
    $operationRetriesOverrides = [
        // The maximum number of automatic retries attempted before returning
        // the error.
        // Default: 3
        'retries' => 10,

        // Exponential backoff settings
        // Retry strategy to signify that we never want to retry an operation
        // even if the error is retryable.
        // Default: StorageClient::RETRY_IDEMPOTENT
        'retryStrategy' => StorageClient::RETRY_ALWAYS,

        // Executes a delay
        // Defaults to utilizing `usleep`.
        // Function signature should match: `function (int $delay) : void`.
        // This function is mostly used internally, so the tests don't wait
        // the time of the delay to run.
        'restDelayFunction' => function ($delay) {
            usleep($delay);
        },

        // Sets the conditions for determining how long to wait between attempts to retry.
        // Function signature should match: `function (int $attempt) : int`.
        // Allows to change the initial retry delay, retry delay multiplier and maximum retry delay.
        'restCalcDelayFunction' => fn ($attempt) => ($attempt + 1) * 100,

        // Sets the conditions for whether or not a request should attempt to retry.
        // Function signature should match: `function (\Exception $ex) : bool`.
        'restRetryFunction' => function (\Exception $e) {
            // Custom logic: ex. only retry if the error code is 404.
            return $e->getCode() === 404;
        },

        // Runs after the restRetryFunction. This might be used to simply consume the
        // exception and $arguments b/w retries. This returns the new $arguments thus allowing
        // modification on demand for $arguments. For ex: changing the headers in b/w retries.
        'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) {
            // logic
        },
    ];
    foreach ($bucket->objects($operationRetriesOverrides) as $object) {
        printf('Object: %s' . PHP_EOL, $object->name());
    }
}

Python

כדי לשנות את התנהגות ברירת המחדל של הניסיונות החוזרים, אתם צריכים ליצור עותק של האובייקט google.cloud.storage.retry.DEFAULT_RETRY על ידי שליחת קריאה אליו באמצעות method with_BEHAVIOR. אם כוללים את הפרמטר DEFAULT_RETRY, ספריית הלקוח של Python משתמשת באופן אוטומטי באסטרטגיות השהיה לפני ניסיון חוזר (backoff) כדי לבצע ניסיון חוזר של בקשות.

שימו לב ש-with_predicate לא נתמך בפעולות שמאחזרות או שולחות נתוני מטען ייעודי (payload) לאובייקטים, כמו העלאות והורדות. מומלץ לשנות את המאפיינים אחד אחרי השני. מידע נוסף זמין בחומר העזר בנושא google-api-core Retry.

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

דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.

from google.cloud import storage
from google.cloud.storage.retry import DEFAULT_RETRY


def configure_retries(bucket_name, blob_name):
    """Configures retries with customizations."""
    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"
    # The ID of your GCS object
    # blob_name = "your-object-name"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(blob_name)

    # Customize retry with a timeout of 500 seconds (default=120 seconds).
    modified_retry = DEFAULT_RETRY.with_timeout(500.0)
    # Customize retry with an initial wait time of 1.5 (default=1.0).
    # Customize retry with a wait time multiplier per iteration of 1.2 (default=2.0).
    # Customize retry with a maximum wait time of 45.0 (default=60.0).
    modified_retry = modified_retry.with_delay(initial=1.5, multiplier=1.2, maximum=45.0)

    # blob.delete() uses DEFAULT_RETRY by default.
    # Pass in modified_retry to override the default retry behavior.
    print(
        f"The following library method is customized to be retried according to the following configurations: {modified_retry}"
    )

    blob.delete(retry=modified_retry)
    print(f"Blob {blob_name} deleted with a customized retry strategy.")

Ruby

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

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

def configure_retries bucket_name: nil, file_name: nil
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The ID of your GCS object
  # file_name = "your-file-name"

  require "google/cloud/storage"

  # Creates a client
  storage = Google::Cloud::Storage.new(

    # The maximum number of automatic retries attempted before returning
    # the error.
    #
    # Customize retry configuration with the maximum retry attempt of 5.
    retries: 5,

    # The total time in seconds that requests are allowed to keep being retried.
    # After max_elapsed_time, an error will be returned regardless of any
    # retry attempts made during this time period.
    #
    # Customize retry configuration with maximum elapsed time of 500 seconds.
    max_elapsed_time: 500,

    # The initial interval between the completion of failed requests, and the
    # initiation of the subsequent retrying request.
    #
    # Customize retry configuration with an initial interval of 1.5 seconds.
    base_interval: 1.5,

    # The maximum interval between requests. When this value is reached,
    # multiplier will no longer be used to increase the interval.
    #
    # Customize retry configuration with maximum interval of 45.0 seconds.
    max_interval: 45,

    # The multiplier by which to increase the interval between the completion
    # of failed requests, and the initiation of the subsequent retrying request.
    #
    # Customize retry configuration with an interval multiplier per iteration of 1.2.
    multiplier: 1.2
  )

  # Uses the retry configuration set during the client initialization above with 5 retries
  file = storage.service.get_file bucket_name, file_name

  # Maximum retry attempt can be overridden for each operation using options parameter.
  storage.service.delete_file bucket_name, file_name, options: { retries: 4 }
  puts "File #{file.name} deleted with a customized retry strategy."
end

ממשקי API בארכיטקטורת REST

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

אלגוריתם של השהיה מעריכית לפני ניסיון חוזר (exponential backoff)

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

דפוסים לא מומלצים לניסיונות חוזרים

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

ניסיון חוזר ללא השהיה

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

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

ניסיונות חוזרים ללא תנאי של פעולות שהן לא אידמפוטנטיות

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

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

ניסיון חוזר לתיקון שגיאות שלא ניתן לנסות שוב

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

איך להימנע מכך: סווגו את השגיאות לשגיאות זמניות (שאפשר לנסות שוב) ולשגיאות קבועות (שאי אפשר לנסות שוב). נסו שוב רק שגיאות זמניות כמו קודי HTTP‏ 408,‏ 429 ו-5xx, או בעיות ספציפיות בחיבור. אם השגיאות קבועות, צריך לתעד אותן ביומן ולטפל בגורם הבסיסי שלהן בהתאם.

התעלמות ממגבלות הניסיונות החוזרים

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

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

שכבות מיותרות של ניסיונות חוזרים

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

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

המאמרים הבאים