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

בדף הזה מוסבר איך הכלים של 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# ‎.

Go

כשמאתחלים לקוח אחסון, תיקבע תצורת ברירת המחדל של הניסיונות החוזרים. אם לא משנים את הערכים, האפשרויות בתצורה מוגדרות לערכי ברירת המחדל. המשתמשים יכולים להגדיר התנהגות של ניסיונות חוזרים ששונה מברירת המחדל לקריאה לספרייה יחידה (באמצעות 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) מבצע ניסיון חוזר של בקשות באמצעות הגדלה אקספוננציאלית של זמני ההמתנה בין הבקשות, עד למשך ההשהיה המקסימלי. בדרך כלל, כדאי להשתמש בהשהיה מעריכית לפני ניסיון חוזר עם רעידות כדי לבצע ניסיון חוזר של בקשות שעומדות גם בקריטריונים של התגובה וגם בקריטריונים של אידמפוטנטיות. למידע נוסף על שיטות מומלצות להטמעה של ניסיונות חוזרים אוטומטיים עם השהיה מעריכית לפני ניסיון חוזר, ראו טיפול בכשלים מדורגים.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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