בדף הזה מוסבר איך הכלים של Cloud Storage מבצעים ניסיונות חוזרים של בקשות שנכשלו ואיך מתאימים אישית את ההתנהגות של הניסיונות החוזרים. כמו כן מתוארים השיקולים לביצוע ניסיון חוזר של בקשות.
סקירה כללית
יש שני גורמים שקובעים אם בטוח לבצע ניסיון חוזר של בקשה:
התגובה שאתם מקבלים מהבקשה.
האידמפוטנטיות של הבקשה.
התגובה
התגובה שאתם מקבלים מהבקשה תעיד אם כדאי או לא כדאי לבצע ניסיון חוזר לבקשה. בדרך כלל, אפשר לבצע ניסיון חוזר לתגובות שקשורות לבעיות זמניות. לעומת זאת, תגובה שקשורה לשגיאות קבועות מעידה על כך שצריך לבצע שינויים לפני שמבצעים ניסיון חוזר לבקשה, למשל שינוי בהרשאות או בהגדרות. התגובות הבאות מציינות בעיות זמניות, שכדאי לבצע ניסיון חוזר כשמקבלים אותן:
- קודי תגובה של HTTP:
408,429ו-5xx. - זמנים קצובים לתפוגה של שקעים וניתוקים של TCP.
מידע נוסף מופיע במאמרים על קודי הסטטוס וקודי השגיאה של JSON ושל XML.
האידמפוטנטיות
אם בקשה היא אידמפוטנטית, אפשר לבצע אותה שוב ושוב בלי לשנות את מצב הסיום של משאב היעד, כך שבכל פעם מתקבל אותו מצב סיום. לדוגמה, פעולות של רשימה הן תמיד אידמפוטנטיות כי הן לא משנות את המשאבים. לעומת זאת, יצירה של התראת Pub/Sub חדשה היא אף פעם לא אידמפוטנטית, כי היא יוצרת מזהה התראה חדש בכל פעם שהבקשה מצליחה.
הדוגמאות הבאות הן מציגות תנאים שגורמים לפעולה להיות אידמפוטנטית:
לפעולה יש אותה השפעה גלויה על משאב היעד, גם אם נשלחת בקשה לביצוע הפעולה באופן רציף.
הפעולה מצליחה רק פעם אחת.
לפעולה אין השפעה גלויה על המצב של משאב היעד.
כשמקבלים תגובה שאפשר לנסות שוב, אתם צריכים לבחון אם הבקשה היא אידמפוטנטית, כי ניסיון חוזר של בקשות שאינן אידמפוטנטיות עשוי להוביל למרוץ תהליכים ולהתנגשויות אחרות.
אידמפוטנטיות מותנית
קבוצת משנה של בקשות הן בקשות עם אידמפוטנטיות מותנית, כלומר שהן אידמפוטנטיות רק אם הן כוללות ארגומנטים אופציונליים ספציפיים. לגבי פעולות שהן בטוחות לביצוע ניסיון חוזר באופן מותנה, אפשר לבצע ניסיון חוזר שלהן כברירת מחדל רק אם הן עומדות בתנאי. Cloud Storage מקבל תנאים מקדימים ו-ETags כתנאים של בקשות.
אידמפוטנטיות של פעולות
בטבלה הבאה מפורטות הפעולות של Cloud Storage לפי קטגוריות של אידמפוטנטיות.
| האידמפוטנטיות | פעולות |
|---|---|
| תמיד אידמפוטנטית |
|
| אידמפוטנטית באופן מותנה |
|
| אף פעם לא אידמפוטנטית |
|
1השדה הזה זמין לשימוש ב-API בפורמט JSON. לרשימת השדות שזמינים לשימוש בספריות הלקוח, אפשר לעיין במסמכי התיעוד של ספריית הלקוח הרלוונטית.
איך הכלים של Cloud Storage מטמיעים אסטרטגיות של ניסיונות חוזרים
המסוף
מסוף Google Cloud שולח בקשות ל-Cloud Storage בשמכם ומטפל בכל השהיה לפני ניסיון חוזר (backoff) שנדרשת.
שורת הפקודה
הפקודות gcloud storage יבצעו ניסיון חוזר כשתקבלו את השגיאות שמפורטות בקטע התגובה, בלי שתצטרכו לבצע פעולה נוספת.
יכול להיות שתצטרכו לנקוט פעולה לגבי שגיאות אחרות, כמו:
פרטי הכניסה לא תקינים או שההרשאות לא מספיקות.
הרשת אינה נגישה בגלל בעיה בהגדרה של שרת proxy.
במקרה של שגיאות שמאפשרות ניסיון חוזר, ה-CLI של gcloud יבצע ניסיון חוזר של הבקשות באמצעות אסטרטגיית השהיה מעריכית בינארית קטועה לפני ניסיון חוזר. כברירת מחדל, מספר הניסיונות החוזרים המקסימלי ב-CLI של gcloud הוא 32.
ספריות לקוח
C++
כברירת מחדל, הפעולות תומכות בביצוע ניסיונות חוזרים לקודי שגיאות HTTP הבאים, וכן לשגיאות שקע שמציינות שהחיבור נותק או שלא נוצר בצורה תקינה.
408 Request Timeout429 Too Many Requests500 Internal Server Error502 Bad Gateway503 Service Unavailable504 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 Timeout429 Too Many Requests500 Internal Server Error502 Bad Gateway503 Service Unavailable504 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.
- ביצוע ניסיון חוזר הוא בטוח אם ה-method מוסיפה
כברירת המחדל, RetryPolicy מוגדר כ-RetryPolicy.RetryIdempotent. לדוגמאות איך לשנות את התנהגות ברירת המחדל של ניסיונות חוזרים, אפשר לעיין בחלק התאמה אישית של ניסיונות חוזרים.
Java
כברירת מחדל, הפעולות תומכות בביצוע ניסיונות חוזרים לשגיאות הבאות:
- שגיאות התחברות:
-
Connection reset by peer: המשמעות היא ש- Google Cloud איפס את החיבור. -
Unexpected connection closure: המשמעות היא ש- Google Cloud סגר את החיבור.
-
- קודי HTTP:
408 Request Timeout429 Too Many Requests500 Internal Server Error502 Bad Gateway503 Service Unavailable504 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 Timeout429 Too Many Requests500 Internal Server Error502 Bad Gateway503 Service Unavailable504 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 Timeout429 Too Many Requests500 Internal Server Error502 Bad Gateway503 Service Unavailable504 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) לאובייקטים, כמו העלאות והורדות) ConnectionErrorhttp.client.ResponseNotReadyurllib3.exceptions.TimeoutError
- קודי HTTP:
408 Request Timeout429 Too Many Requests500 Internal Server Error502 Bad Gateway503 Service Unavailable504 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עצמו. ל-methodset_iam_policy()במחלקות אחרות, המשמעות היא שצריך להגדיר את ה-etag בארגומנט 'policy' שמועבר ל-method.
- ביצוע ניסיון חוזר הוא בטוח אם ה-method מוסיפה
Ruby
כברירת מחדל, הפעולות תומכות בביצוע ניסיונות חוזרים לקודי השגיאה הבאים:
- שגיאות התחברות:
SocketErrorHTTPClient::TimeoutErrorErrno::ECONNREFUSEDHTTPClient::KeepAliveDisconnected
- קודי HTTP:
408 Request Timeout429 Too Many Requests5xx 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++.
C#
אי אפשר להתאים אישית את אסטרטגיית ברירת המחדל של הניסיונות החוזרים שבה משתמשת ספריית הלקוח C# .
Go
כשמאתחלים לקוח אחסון, תיקבע תצורת ברירת המחדל של הניסיונות החוזרים. אם לא משנים את הערכים, האפשרויות בתצורה מוגדרות לערכי ברירת המחדל. המשתמשים יכולים להגדיר התנהגות של ניסיונות חוזרים ששונה מברירת המחדל לקריאה לספרייה יחידה (באמצעות BucketHandle.Retryer ו-ObjectHandle.Retryer) או לכל הקריאות שנשלחות על ידי לקוח (באמצעות Client.SetRetry). כדי לשנות את ההתנהגות של ניסיונות חוזרים, צריך להעביר את האפשרויות הרלוונטיות של RetryOptions לאחת מה-methods הבאות.
דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.
Java
כשמאתחלים את Storage, מתבצע גם אתחול של מכונת RetrySettings. אם לא משנים את הערכים, האפשרויות ב-RetrySettings מוגדרות לערכי ברירת המחדל. כדי לשנות את התנהגות ברירת המחדל של ניסיון חוזר אוטומטי, מעבירים את StorageRetryStrategy בהתאמה אישית אל StorageOptions שמשמש להרכבת המכונה Storage. כדי לשנות פרמטרים סקלריים אחרים, אתם צריכים להעביר את RetrySettings בהתאמה אישית אל StorageOptions שמשמש להרכבת המכונה Storage.
הדוגמה הבאה מראה איך להתאים אישית את ההתנהגות של ניסיונות חוזרים:
Node.js
כשמאתחלים את Cloud Storage, מתבצע גם אתחול של קובץ התצורה retryOptions. אם לא משנים את הערכים, האפשרויות בתצורה מוגדרות לערכי ברירת המחדל. כדי לשנות את התנהגות ברירת המחדל של הניסיונות החוזרים, במהלך האתחול מעבירים את התצורה של הניסיונות החוזרים retryOptions ל-constructor של האחסון.
ספריית הלקוח של Node.js יכולה להשתמש באופן אוטומטי באסטרטגיות השהיה לפני ניסיון חוזר (backoff) כדי לבצע ניסיון חוזר של בקשות עם הפרמטר autoRetry.
דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.
PHP
כשמאתחלים לקוח אחסון, תיקבע תצורת ברירת המחדל של הניסיונות החוזרים. אם לא משנים את הערכים, האפשרויות בתצורה מוגדרות לערכי ברירת המחדל. המשתמשים יכולים להגדיר התנהגות של ניסיונות חוזרים ששונה מברירת המחדל ללקוח או לקריאה לפעולה יחידה על ידי העברת אפשרויות החלפה במערך.
דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.
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.
דוגמת הקוד הבאה מראה איך להתאים אישית את ההתנהגות של הניסיונות החוזרים.
Ruby
כשמאתחלים את לקוח האחסון, כל ההגדרות של הניסיונות החוזרים נקבעות לערכים שמוצגים בטבלה שלמעלה. כדי לשנות את התנהגות ברירת המחדל של הניסיונות החוזרים, אתם צריכים להעביר את התצורות של הניסיונות החוזרים בזמן האתחול של לקוח האחסון.
כדי לשנות את מספר הניסיונות החוזרים לפעולה מסוימת, מעבירים את retries בפרמטר options של הפעולה.
ממשקי API ל-REST
אתם צריכים להשתמש באלגוריתם של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) כדי להטמיע את האסטרטגיה שלכם לביצוע ניסיונות חוזרים.
אלגוריתם של השהיה מעריכית לפני ניסיון חוזר (exponential backoff)
אלגוריתם של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) מבצע ניסיון חוזר של בקשות באמצעות הגדלה אקספוננציאלית של זמני ההמתנה בין הבקשות, עד למשך ההשהיה המקסימלי. בדרך כלל, כדאי להשתמש בהשהיה מעריכית לפני ניסיון חוזר עם רעידות כדי לבצע ניסיון חוזר של בקשות שעומדות גם בקריטריונים של התגובה וגם בקריטריונים של אידמפוטנטיות. למידע נוסף על שיטות מומלצות להטמעה של ניסיונות חוזרים אוטומטיים עם השהיה מעריכית לפני ניסיון חוזר, ראו טיפול בכשלים מדורגים.
ניסיון חוזר לתיקון שגיאות
מומלץ להשתמש במנגנוני הניסיון החוזר המובנים או להתאים אותם אישית במקרים הרלוונטיים. מידע נוסף זמין במאמר בנושא התאמה אישית של ניסיונות חוזרים. בין אם אתם משתמשים במנגנוני הניסיון החוזר שמוגדרים כברירת מחדל, מבצעים בהם התאמה אישית או מטמיעים לוגיקה משלכם לניסיון חוזר, חשוב להימנע מדפוסי התנהגות אנטי-תבניתיים נפוצים, כי הם עלולים להחמיר את הבעיות במקום לפתור אותן.
ניסיון חוזר ללא השהיה
ניסיון חוזר לשלוח בקשות באופן מיידי או עם השהיות קצרות מאוד עלול להוביל לכשלים מצטברים, כלומר כשלים שעלולים להפעיל כשלים אחרים.
איך להימנע מהבעיה: מטמיעים השהיה מעריכית לפני ניסיון חוזר עם רעידות. האסטרטגיה הזו מגדילה בהדרגה את זמן ההמתנה בין הניסיונות החוזרים, ומוסיפה אלמנט אקראי כדי למנוע מצב שבו הניסיונות החוזרים יוצרים עומס יתר על השירות.
ניסיון חוזר ללא תנאי של פעולות שהן לא אידמפוטנטיות
ביצוע חוזר של פעולות שהן לא אידמפוטנטיות עלול להוביל לתופעות לוואי לא רצויות, כמו החלפה או מחיקה לא מכוונת של נתונים.
איך אפשר להימנע מכך: חשוב להבין היטב את מאפייני האידמפוטנטיות של כל פעולה, כפי שמפורט בקטע אידמפוטנטיות של פעולות. בפעולות שהן לא אידמפוטנטיות, צריך לוודא שהלוגיקה של הניסיון החוזר יכולה לטפל בכפילויות פוטנציאליות או להימנע מניסיון חוזר שלהן לחלוטין. צריך להיזהר מניסיונות חוזרים שעלולים להוביל לתנאי מירוץ.
ניסיון חוזר לתיקון שגיאות שלא ניתן לנסות שוב
יכול להיות שיהיו בעיות אם תנסו שוב לפתור את כל השגיאות. שגיאות מסוימות, למשל שגיאות הרשאה או בקשות לא תקינות, הן קבועות. ניסיון חוזר לשלוח אותן בלי לטפל בגורם הבסיסי לא יצליח, ועלול לגרום לכך שהאפליקציות ייתקעו בלולאה אינסופית.
איך אפשר להימנע מכך: צריך לסווג את השגיאות לשגיאות זמניות (שניתן לנסות שוב) ולשגיאות קבועות (שלא ניתן לנסות שוב). כדאי לנסות שוב רק שגיאות זמניות כמו קודי HTTP 408, 429 ו-5xx, או בעיות ספציפיות בחיבור. אם השגיאות הן קבועות, צריך לרשום אותן ביומן ולטפל בגורם הבסיסי בצורה מתאימה.
התעלמות ממגבלות הניסיונות החוזרים
ניסיון חוזר ללא הגבלה עלול לגרום לניצול יתר של משאבים באפליקציה או לשליחת בקשות לשירות שלא יחזור לפעולה ללא התערבות.
איך אפשר להימנע מכך: צריך להתאים את מגבלות הניסיון החוזר לאופי של עומס העבודה. בעומסי עבודה שרגישים לזמן האחזור, כדאי להגדיר משך זמן מקסימלי כולל לניסיונות חוזרים כדי להבטיח תגובה או כשל בזמן. לעומסי עבודה באצווה, שבהם יכול להיות שיש סבילות לתקופות ארוכות יותר של ניסיון חוזר לשגיאות זמניות בצד השרת, כדאי להגדיר מגבלה כוללת גבוהה יותר של ניסיונות חוזרים.
שכבות מיותרות של ניסיונות חוזרים
הוספה של לוגיקה מותאמת אישית לניסיון חוזר ברמת האפליקציה בנוסף למנגנוני הניסיון החוזר הקיימים עלולה להוביל למספר מוגזם של ניסיונות חוזרים. לדוגמה, אם האפליקציה מנסה לבצע פעולה שלוש פעמים, וספריית הלקוח הבסיסית מנסה לבצע אותה שלוש פעמים גם עבור כל אחד מהניסיונות של האפליקציה, יכול להיות שיהיו תשעה ניסיונות חוזרים. שליחה של מספר רב של ניסיונות חוזרים לשגיאות שלא ניתן לנסות לשלוח שוב עלולה להוביל להגבלת קצב הבקשות, וכך להגביל את קצב העברת הנתונים של כל עומסי העבודה. מספר גבוה של ניסיונות חוזרים עלול גם להגדיל את זמן האחזור של הבקשות בלי לשפר את שיעור ההצלחה.
איך אפשר להימנע מכך: מומלץ להשתמש במנגנוני הניסיון החוזר המובנים ולהגדיר אותם. אם אתם חייבים להטמיע ניסיונות חוזרים ברמת האפליקציה, למשל עבור לוגיקה עסקית ספציפית שמשתרעת על פני כמה פעולות, עליכם לעשות זאת תוך הבנה ברורה של התנהגות הניסיון החוזר הבסיסית. כדי למנוע השפעות מכפילות, כדאי להשבית או להגביל באופן משמעותי את הניסיונות החוזרים באחת מהשכבות.
המאמרים הבאים
- מידע נוסף על תנאים מוקדמים של בקשות