מדריך לענן האביב נטפליקס - Hystrix

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

במדריך זה נסקור את Spring Cloud Netflix Hystrix - ספריית סובלנות התקלות. נשתמש בספרייה וניישם את תבנית הארגון Circuit Breaker, המתארת ​​אסטרטגיה כנגד כישלון המפלס ברמות שונות ביישום.

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

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

2. מפיק REST

כדי ליצור תרחיש, המדגים את דפוס המפסק, ראשית אנו זקוקים לשירות. נקרא לזה "REST Producer" מכיוון שהוא מספק נתונים עבור "REST Consumer" המאופשר ב- Hystrix, אותם ניצור בשלב הבא.

בואו ניצור פרויקט Maven חדש באמצעות ה- קפיץ-אתחול-רשת תלות:

 org.springframework.boot spring-boot-starter-web 2.2.6.RELEASE 

הפרויקט עצמו נשמר בפשטות בכוונה. הוא מורכב מממשק בקר עם אחד @ בקשת מיפוי שיטת ה- GET המבוארת מחזירה פשוט א חוּט, א @ RestController יישום ממשק זה ו- @ SpringBootApplication.

נתחיל מהממשק:

ממשק ציבורי GreetingController {@GetMapping ("/ greeting / {username}") ברכת מחרוזת (@PathVariable ("שם משתמש") שם משתמש מחרוזת); }

והיישום:

@RestController מחלקה ציבורית GreetingControllerImpl מיישם GreetingController {@Override public String String (@PathVariable ("שם משתמש") מחרוזת שם משתמש) {return String.format ("שלום% s! \ N", שם משתמש); }}

לאחר מכן נרשום את מחלקת היישומים הראשית:

@ SpringBootApplication מחלקה ציבורית RestProducerApplication {public static void main (String [] args) {SpringApplication.run (RestProducerApplication.class, args); }}

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

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

בואו נציין יציאה של 9090 ושם של מפיק מנוחה בשלנו application.properties קוֹבֶץ:

server.port = 9090 spring.application.name = מפיק מנוחה

כעת אנו יכולים לבדוק את המפיק שלנו באמצעות cURL:

$> תלתל // localhost: 9090 / ברכה / Cid Hello Cid!

3. מנוחת הצרכן עם היסטריקס

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

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

 org.springframework.cloud spring-cloud-starter-hystrix 1.4.7.RELEASE org.springframework.boot spring-boot-starter-web 2.2.6.RELEASE org.springframework.boot spring-boot-starter-thymeleaf 2.2.6. לְשַׁחְרֵר 

כדי שהמפסק יעבוד, Hystix יסרוק @רְכִיב אוֹ @שֵׁרוּת שיעורים ביאורים עבור @HystixCommand שיטות ביאור, ליישם לו פרוקסי ולפקח על קריאותיו.

אנחנו הולכים ליצור @שֵׁרוּת מחלקה ראשונה, שתוזרק לא @בקר. מכיוון שאנו בונים יישום אינטרנט באמצעות Thymeleaf, אנו זקוקים גם לתבנית HTML שתשמש כתצוגה.

זה יהיה להזרקה שלנו @שֵׁרוּת יישום א @HystrixCommand בשיטת נסיגה משויכת. חיסרון זה צריך להשתמש באותה חתימה כמו במקור:

@Service בכיתה ציבורית GreetingService {@HystrixCommand (fallbackMethod = "defaultGreeting") ציבורי מחרוזת getGreeting (שם משתמש מחרוזת) {החזר RestTemplate חדש () .getForObject ("// localhost: 9090 / ברכה / {שם משתמש}", String.class, שם משתמש ); } פרטית מחרוזת defaultGreeting (שם משתמש מחרוזת) {להחזיר "שלום משתמש!"; }}

RestConsumerApplication תהיה מחלקת היישומים העיקרית שלנו. ה @EnableCircuitBreaker ביאור יסרוק את מסלול הכיתה עבור כל יישום מפסק תואם.

כדי להשתמש במפורש ב- Hystrix, עלינו לציין את המחלקה הזו @EnableHystrix:

@SpringBootApplication @EnableCircuitBreaker מחלקה ציבורית RestConsumerApplication {public static void main (String [] args) {SpringApplication.run (RestConsumerApplication.class, args); }}

נגדיר את הבקר באמצעות שלנו GreetingService:

@Controller מחלקה ציבורית GreetingController {@Autowired פרטי GreetingService greetingService; @GetMapping ("/ get-greeting / {username}") ציבורי מחרוזת getGreeting (מודל דגם, @ PathVariable ("שם משתמש") שם משתמש מחרוזת) {model.addAttribute ("שלום", greetingService.getGreeting (שם משתמש)); להחזיר "נוף ברכה"; }}

והנה תבנית ה- HTML:

   ברכות מהיסטריקס 

כדי להבטיח שהיישום מאזין ביציאה מוגדרת, שמנו את הדברים הבאים ב- application.properties קוֹבֶץ:

server.port = 8080

כדי לראות מפסק של Hystix בפעולה, אנו מתחילים את הצרכן שלנו ומפנים את הדפדפן אליו // localhost: 8080 / קבל ברכה / Cid. בנסיבות רגילות, יוצג הדברים הבאים:

שלום סיד!

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

שלום משתמש!

4. מנוחת הצרכן עם היסטריקס ופיין

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

היתרון הוא שמאוחר יותר נוכל לשחזר בקלות את ממשק לקוח Feign שלנו כדי להשתמש ב- Spring Netflix Eureka לגילוי שירותים.

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

 com.baeldung.spring.cloud spring-cloud-hystrix-rest-producer 1.0.0-SNAPSHOT org.springframework.cloud spring-cloud-starter-feign 1.1.5.RELEASE 

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

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

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

@FeignClient (name = "rest-producer" url = "// localhost: 9090", fallback = GreetingClient.GreetingClientFallback.class) ממשק ציבורי GreetingClient מרחיב את GreetingController {@Component public static class GreetingClientFallback מיישם GreetingController {@Override Public String PathVariable ("שם משתמש") שם משתמש מחרוזת) {החזר "שלום משתמש!"; }}}

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

בתוך ה RestConsumerFeignApplication, נביא הערה נוספת שתאפשר שילוב של פייג ', למעשה, @EnableFeignClients, לשיעור היישומים הראשי:

@SpringBootApplication @EnableCircuitBreaker @EnableFeignClients class class RestConsumerFeignApplication {public static void main (String [] args) {SpringApplication.run (RestConsumerFeignApplication.class, args); }}

אנו מתכוונים לשנות את הבקר לשימוש בלקוח Feign חוטי אוטומטי, במקום שהוזרק בעבר @שֵׁרוּת, כדי לאחזר את ברכתנו:

@Controller בכיתה ציבורית GreetingController {@Autowired פרטי GreetingClient greetingClient; @GetMapping ("/ קבל-שלום / {שם משתמש}") ציבורי מחרוזת getGreeting (מודל דגם, @ PathVariable ("שם משתמש") שם משתמש מחרוזת) {model.addAttribute ("ברכה", greetingClient.greeting (שם משתמש)); להחזיר "נוף ברכה"; }}

כדי להבדיל דוגמה זו מהקודמת, נשנה את יציאת האזנה ליישום ב- application.properties:

server.port = 8082

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

5. זיכרון מטמון עם היסטריקס

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

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

5.1. התקנה ותצורה

תן לנו להוסיף את אביב-ענן-סטרטר-היסטריקס תלות במודול הדירוג שלנו:

 org.springframework.cloud spring-cloud-starter-hystrix 

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

בואו נעדכן את דירוג שירות לעטוף את שיטות שאילתת מסד הנתונים בפקודה Hystrix באמצעות @HystrixCommand וקבע את התצורה עם חיסרון לקריאה מ- Redis:

@HystrixCommand (commandKey = "ratingsByIdFromDB", fallbackMethod = "findCachedRatingById", ignoreExceptions = {RatingNotFoundException.class}) דירוג ציבורי findRatingById (Long ratingId) {return Optional.ofNullable (ratingRepository.findOne ((ratingId)) () RatingNotFoundException חדש ("דירוג לא נמצא. מזהה:" + ratingId)); } דירוג ציבורי findCachedRatingById (Long ratingId) {return cacheRepository.findCachedRatingById (ratingId); }

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

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

@EnableHystrix @EnableTransactionManagement (order = Ordered.LOWEST_PRECEDENCE, mode = AdviceMode.ASPECTJ) class class RatingServiceApplication {@Bean @Primary @Order (value = Ordered.HIGHEST_PRECEDENCE) HystrixCommandAspect hystrixAspect () commandAspect (); } // שעועית אחרת, תצורות}

כאן, התאמנו את ייעוץ ה- AOP של עסקת האביב כך שיהיה לו עדיפות נמוכה יותר מאשר הייעוץ של Hystrix AOP.

5.2. בדיקת היסטריקס Fallback

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

בואו להעתיק את ספריית H2 (h2-1.4.193.jar) לספרייה ידועה והפעל את שרת H2:

> java -cp h2-1.4.193.jar org.h2.tools.Server-שרת TCP TCP פועל ב- tcp: //192.168.99.1: 9092 (רק חיבורים מקומיים)

בואו ונעדכן את כתובת האתר של מקור המודול שלנו ב דירוג-service.properties להצביע על שרת H2 זה:

spring.datasource.url = jdbc: h2: tcp: // localhost / ~ / דירוגים

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

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

6. שימוש בהיקפים

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

@HystrixCommand (fallbackMethod = "getSomeDefault", commandProperties = {@HystrixProperty (name = "execution.isolation.strategy", value = "SEMAPHORE")})

7. לוח המחוונים של Hystrix

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

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

 org.springframework.cloud spring-cloud-starter-hystrix-dashboard 1.4.7.RELEASE org.springframework.boot spring-boot-starter-actuator 2.2.6.RELEASE 

יש להפעיל את הראשון באמצעות ביאור א @תְצוּרָה עם @EnableHystrixDashboard והאחרון מאפשר באופן אוטומטי את המדדים הנדרשים ביישום האינטרנט שלנו.

לאחר שסיימנו להפעיל מחדש את היישום, נפנה לדפדפן // localhost: 8080 / hystrix, הזן את כתובת ה- URL של המדדים של זרם Hystrix והתחל במעקב.

לבסוף, עלינו לראות משהו כזה:

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

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

8. מסקנה

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

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

כרגיל, אנו יכולים למצוא את המקורות ב- GitHub.