ספריות הלקוח של Cloud ל-Java משתמשות בניסיונות חוזרים כדי לטפל בכשלים בלתי צפויים וחולפים (כלומר, השרת לא זמין באופן זמני). יכול להיות שיידרשו כמה ניסיונות כדי לקבל תגובה מהשרת.
ערכי ברירת המחדל לניסיון חוזר נבחרים על ידי הצוות שמפעיל את שירות הענן. ערכי הניסיון החוזר האלה מוגדרים לכל RPC. שירות יכול לבחור להפעיל ניסיונות חוזרים רק עבור קבוצת משנה של RPCs. יכול להיות שכל RPC של שירות מוגדר באופן שונה.
פרמטרים של ניסיון חוזר
יש שני סוגים של פרמטרים לניסיון חוזר שאפשר להגדיר בספריות לקוח:
- קוד סטטוס של ניסיון חוזר: קבוצת קודי סטטוס לניסיון חוזר.
- זמן קצוב לתפוגה של ניסיון חוזר או גבולות של ניסיון: אפשר להגדיר RetrySettings כדי להגדיר את הגבולות.
מיקום ברירת המחדל של הגדרות הניסיון החוזר של RPC
הגדרות ברירת המחדל של הניסיונות החוזרים מוגדרות בקובץ {Client}StubSettings שנוצר. בדוגמה הבאה, שמתבססת על קריאה לשירות מרוחק (RPC) מסוג ExportAssets ב-Java-Asset v3.64.0, מוגדרות הגדרות ברירת המחדל לניסיון חוזר:
קודי סטטוס של ניסיון חוזר: מוגדרים בקובץ
AssetServiceStubSettings.java. דוגמה:ImmutableMap.Builder<String, ImmutableSet<StatusCode.Code>> definitions = ImmutableMap.builder(); definitions.put("no_retry_0_codes", ImmutableSet.copyOf(Lists.<StatusCode.Code>newArrayList())); // ... More StatusCode configurations RETRYABLE_CODE_DEFINITIONS = definitions.build();פרמטרים של ניסיון חוזר: מוגדרים בקובץ
AssetServiceStubSettings.java. דוגמה:ImmutableMap.Builder<String, RetrySettings> definitions = ImmutableMap.builder(); RetrySettings settings = null; settings = RetrySettings.newBuilder() .setInitialRpcTimeoutDuration(Duration.ofMillis(60000L)) .setRpcTimeoutMultiplier(1.0) .setMaxRpcTimeoutDuration(Duration.ofMillis(60000L)) .setTotalTimeoutDuration(Duration.ofMillis(60000L)) .build(); definitions.put("no_retry_0_params", settings); // ... More RetrySettings configurations RETRY_PARAM_DEFINITIONS = definitions.build();
שתי ההגדרות ממופות ל-RPC בקובץ AssetServiceStubSettings.java. דוגמה:
builder
.exportAssetsSettings()
.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes"))
.setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params"));
מושגים שקשורים לניסיונות חוזרים בספריות לקוח
הפעלת ניסיונות חוזרים מאפשרת ל-RPC לנסות כמה פעמים לבצע קריאה מוצלחת. קריאה מוצלחת היא תגובה משרת שמחזירה קוד סטטוס OK (מ-gRPC) או קוד סטטוס 2xx (מ-HttpJson).
ניסיון לעומת פעולה
ההגדרה הבאה של RetrySettings משנה את הגדרות הניסיון החוזר גם עבור ניסיון של RPC וגם עבור פעולה:
settings =
RetrySettings.newBuilder()
.setInitialRetryDelayDuration(Duration.ofMillis(100L))
.setRetryDelayMultiplier(1.3)
.setMaxRetryDelayDuration(Duration.ofMillis(60000L))
.setInitialRpcTimeoutDuration(Duration.ofMillis(60000L))
.setRpcTimeoutMultiplier(1.0)
.setMaxRpcTimeoutDuration(Duration.ofMillis(60000L))
.setTotalTimeoutDuration(Duration.ofMillis(60000L))
.build();
ניסיון RPC הוא הניסיון הבודד שבוצע, ופעולת RPC היא אוסף של כל הניסיונות שבוצעו. קריאה יחידה ל-RPC תכלול ניסיון אחד או יותר בפעולה יחידה.
ההגדרות הבאות קובעות את הגבולות של RPC (ניסיון):
-
setInitialRetryDelayDuration: השהיה לפני הניסיון הראשון. -
setRetryDelayMultiplier: מכפיל העיכוב שמוחל בין כל ניסיון. -
setMaxRetryDelayDuration: ההשהיה המקסימלית האפשרית לניסיון. -
setInitialRpcTimeoutDuration: הזמן הקצוב לתפוגה לניסיון הראשון. -
setRpcTimeoutMultiplier: מכפיל של פסק זמן שמוחל בין כל ניסיון. -
setMaxRpcTimeoutDuration: הזמן הקצוב לתפוגה המקסימלי האפשרי לניסיון.
ההגדרות הבאות קובעות את הגבולות הכוללים של RPC (פעולה):
-
setTotalTimeoutDuration: הזמן הכולל שמוקצב לפעולה כולה. -
setMaxAttempts: מספר הניסיונות המקסימלי המותר.
כשמנסים שוב לבצע RPC
מערכת Google תנסה שוב לבצע RPC אם מתרחש אחד משני התרחישים הבאים:
- הספרייה מקבלת קוד סטטוס לא מוצלח וקוד הסטטוס מסומן כאפשרות לניסיון חוזר.
- קריאה ל-RPC חורגת מהגבולות של ה-RPC הספציפי, אבל עדיין נמצאת בתוך הגבולות הכוללים של ה-RPC.
אם רק אחד מהתרחישים נכון, או אם אף אחד מהתרחישים לא נכון, לא יתבצע ניסיון חוזר של ה-RPC.
לדוגמה, אם לא חלף הזמן הכולל להמתנה, אבל הניסיון האחרון מקבל קוד סטטוס שלא ניתן לנסות שוב.
בנוסף, כשמגדירים את הגבולות של ה-RPC, אפשר להגדיר את הגבולות של כל ניסיון וגם את הגבולות הכוללים של ה-RPC. אלגוריתם הניסיון החוזר יבטיח שהגבולות של ניסיון בודד יהיו בתוך הגבולות של ה-RPC הכולל.
השהיה מעריכית לפני ניסיון חוזר (exponential backoff)
השהיה מעריכית לפני ניסיון חוזר (exponential backoff) תנסה שוב לשלוח בקשות עם עיכוב הולך וגדל בין כל ניסיון חוזר. אפשר להגביל את ערך ההשהיה של הניסיון החוזר באמצעות ערך מקסימלי של השהיה של הניסיון החוזר.
לדוגמה, הגדרות הניסיון החוזר הבאות יכולות לגרום לזמני השהיה הבאים:
Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms
- ניסיון 1: השהיה של 100 אלפיות השנייה
- ניסיון שני: השהיה של 200 אלפיות השנייה
- ניסיון 3: השהיה של 400 אלפיות השנייה
- ניסיון 4: השהיה של 500 אלפיות השנייה
- ...
- ניסיון X: השהיה של 500 אלפיות השנייה
רעידות
הוספת שונות אקראית (Jitter) היא שיטה להפצת הקריאות ל-RPC על פני זמן. Google Cloud ספריות הלקוח תמיד מפעילות שונות אקראית לניסיונות חוזרים. כך אפשר לפזר את הניסיונות החוזרים בלי להעמיס על השרת.
הערך האקראי של הג'יטר מחושב על סמך עיכוב הניסיון החוזר. לפני כל ניסיון, אלגוריתם הניסיון החוזר יחשב ערך אקראי בין [1, RETRY_DELAY]. הערך המחושב הזה הוא העיכוב המשוער לפני שהבקשה נשלחת לשרת.
ההגדרות הבאות לניסיון חוזר משתמשות ברעידות ובהשהיה מעריכית לפני ניסיון חוזר.
Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms
העיכובים האפשריים:
- ניסיון 1: השהיה של ערך אקראי בין
[1, 100]אלפיות השנייה - ניסיון שני: השהיה של ערך אקראי בין
[1, 200]אלפיות שנייה - ניסיון 3: השהיה של ערך אקראי בין
[1, 400]אלפיות השנייה - ניסיון 4: השהיה של ערך אקראי בין
[1, 500]ms - ...
- ניסיון X: השהיה של ערך אקראי בין
[1, 500]אלפיות השנייה
דוגמאות לניסיון חוזר
בדוגמאות הבאות מוצגת ההתנהגות של כמה הגדרות של ניסיונות חוזרים.
ללא ניסיון חוזר
בדוגמה הזו מושבתים הניסיונות החוזרים.