הגדרת תצורה של לוגיקה חוזרת באביב אצווה

1. סקירה כללית

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

במדריך המהיר הזה, נבדוק כיצד להגדיר לוגיקה לניסיון חוזר במסגרת Spring Batch.

2. מקרה שימוש לדוגמא

נניח שיש לנו עבודת אצווה שקוראת קובץ CSV קלט:

שם משתמש, userid, transaction_date, transaction_amount sammy, 1234, 31/10/2015, 10000 john, 9999, 3/12/2015, 12321

לאחר מכן הוא מעבד כל רשומה על ידי פגיעה בנקודת קצה של REST כדי להביא את המשתמש גיל ו postCode תכונות:

מחלקה ציבורית RetryItemProcessor מיישמת את ItemProcessor {@Override תהליך עסקה ציבורית (עסקת עסקה) זורק IOException {log.info ("RetryItemProcessor, מנסה לעבד: {}", עסקה); תגובה HttpResponse = fetchMoreUserDetails (transaction.getUserId ()); // לנתח את הגיל וה- PostCode של המשתמש מהתגובה ולעדכן את העסקה ... עסקת החזרה; } ...}

ולבסוף, זה מייצר תפוקה מאוחדת XML:

  10000.0 2015-10-31 00:00:00 1234 סומי 10 430222 ... 

3. הוספת ניסיונות חוזרים ל פריט מעבד

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

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

@Bean Public Step retryStep (מעבד ItemProcessor, כותב ItemWriter) זורק ParseException {return stepBuilderFactory .get ("retryStep") .chunk (10) .reader (itemReader (inputCsv)). מעבד (מעבד) .writer (כותב) .faultTolerant ( ) .retryLimit (3) .retry (ConnectTimeoutException.class) .retry (DeadlockLoserDataAccessException.class) .build (); }

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

4. בדיקת הניסיון חוזר

שיהיה לנו תרחיש בדיקה שבו נקודת הקצה של REST חוזרת גיל ו postCode היה למטה רק לזמן מה. בתרחיש בדיקה זה נקבל ConnectTimeoutException רק עבור שתי שיחות ה- API הראשונות, והשיחה השלישית תצליח:

@Test ציבורי בטל כאשר EndpointFailsTwicePasses3rdTime_thenSuccess () זורק חריג {FileSystemResource expectResult = FileSystemResource חדש (EXPECTED_OUTPUT); FileSystemResource actualResult = FileSystemResource חדש (TEST_OUTPUT); מתי (httpResponse.getEntity ()) .thenReturn (StringEntity חדש ("{\" age \ ": 10, \" postCode \ ": \" 430222 \ "}")); // נכשל בשתי השיחות הראשונות ועובר בפעם השלישית ואילך כאשר (httpClient.execute (any ())) .thenThrow (ConnectTimeoutException חדש ("ספירת זמן קצוב 1")) .thenTrow (חדש ConnectTimeoutException ("ספירת זמן קצוב 2")). thenReturn (httpResponse); JobExecution jobExecution = jobLauncherTestUtils .launchJob (defaultJobParameters ()); JobInstance actualJobInstance = jobExecution.getJobInstance (); ExitStatus actualJobExitStatus = jobExecution.getExitStatus (); assertThat (actualJobInstance.getJobName (), הוא ("retryBatchJob")); assertThat (actualJobExitStatus.getExitCode (), הוא ("הושלם")); AssertFile.assertFileEquals (expectResult, actualResult); }

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

19: 06: 57.742 [main] INFO osbatch.core.job.SimpleStepHandler - שלב ביצוע: [retryStep] 19: 06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - ניסיון לעבד משתמש עם id = 1234 19: 06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - ניסיון לעבד משתמש עם id = 1234 19: 06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - ניסיון לעבד משתמש עם id = 1234 19:06: 57.758 [main] INFO obbatch.service.RetryItemProcessor - ניסיון לעבד משתמש עם id = 9999 19: 06: 57.773 [main] INFO osbatch.core.step.AbstractStep - שלב: [retryStep] מבוצע ב- 31ms

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

@Test הציבור בטל כאשר EndpointAlwaysFail_thenJobFails () זורק חריג {כאשר (httpClient.execute (any ())) .thenTrow (חדש ConnectTimeoutException ("נקודת הקצה למטה")); JobExecution jobExecution = jobLauncherTestUtils .launchJob (defaultJobParameters ()); JobInstance actualJobInstance = jobExecution.getJobInstance (); ExitStatus actualJobExitStatus = jobExecution.getExitStatus (); assertThat (actualJobInstance.getJobName (), הוא ("retryBatchJob")); assertThat (actualJobExitStatus.getExitCode (), הוא ("נכשל")); assertThat (actualJobExitStatus.getExitDescription (), containString ("org.apache.http.conn.ConnectTimeoutException")); }

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

5. קביעת תצורה של ניסיונות חוזרים באמצעות XML

לבסוף, בואו נסתכל על המקבילה ל- XML ​​של התצורות לעיל:

6. מסקנה

במאמר זה למדנו כיצד להגדיר את ההגיון לניסיון חוזר באביב אצווה. בדקנו תצורות Java ו- XML.

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

כמו תמיד, קוד הדוגמה למדריך זה זמין ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found