Sprievodca jarným cloudom Netflix - Hystrix

1. Prehľad

V tomto výučbe sa budeme venovať Spring Cloud Netflix Hystrix - knižnici odolnosti proti chybám. Použijeme knižnicu a implementujeme podnikový vzor Circuit Breaker, ktorý popisuje stratégiu proti kaskádovaniu zlyhaní na rôznych úrovniach v aplikácii.

Princíp je analogický s elektronikou: Hystrix sleduje metódy zlyhania volania na súvisiace služby. Ak dôjde k takejto poruche, otvorí sa obvod a hovor sa presmeruje na záložnú metódu.

Knižnica bude tolerovať poruchy až do limitu. Okrem toho to ponecháva okruh otvorený. Čo znamená, že postúpi všetky nasledujúce volania na záložnú metódu, aby sa zabránilo budúcim zlyhaniam. Tým sa vytvorí časová medzipamäť pre príslušnú službu, ktorá sa má zotaviť z chybného stavu.

2. Producent REST

Na vytvorenie scenára, ktorý demonštruje štruktúru ističa, potrebujeme najskôr službu. Pomenujeme ju „REST Producer“, pretože poskytuje údaje pre „REST Consumer“ s podporou Hystrix, ktorú vytvoríme v ďalšom kroku.

Vytvorme nový projekt Maven pomocou spring-boot-starter-web závislosť:

 org.springframework.boot Spring-Boot-Starter-Web 2.2.6.RELEASE 

Samotný projekt je zámerne udržiavaný jednoduchý. Skladá sa z rozhrania radiča s jedným @RequestMapping komentovaná metóda GET, ktorá sa jednoducho vracia a Reťazec, a @RestController implementácia tohto rozhrania a @SpringBootApplication.

Začneme rozhraním:

verejné rozhranie GreetingController {@GetMapping ("/ pozdrav / {username}") String pozdrav (@PathVariable ("username") String username); }

A implementácia:

@RestController verejná trieda GreetingControllerImpl implementuje GreetingController {@Override public String pozdrav (@PathVariable ("username") String username) {return String.format ("Hello% s! \ N", username); }}

Ďalej si napíšeme hlavnú triedu aplikácií:

@SpringBootApplication verejná trieda RestProducerApplication {public static void main (String [] args) {SpringApplication.run (RestProducerApplication.class, args); }}

Na dokončenie tejto časti zostáva iba nakonfigurovať port aplikácie, na ktorom budeme počúvať. Nepoužívame predvolený port 8080, pretože port by mal zostať vyhradený pre aplikáciu popísanú v ďalšom kroku.

Ďalej definujeme názov aplikácie, aby sme mohli vyhľadať nášho výrobcu z klientskej aplikácie, ktorú uvedieme neskôr.

Potom určíme port 9090 a meno zvyšok výrobca v našom application.properties spis:

server.port = 9090 spring.application.name = rest-producer

Teraz sme schopní vyskúšať nášho výrobcu pomocou nástroja CURL:

$> zvlnenie // localhost: 9090 / pozdrav / Cid Ahoj Cid!

3. ODPOČINOK pre spotrebiteľa S Hystrixom

Pre náš demonštračný scenár budeme implementovať webovú aplikáciu, ktorá využíva službu REST z predchádzajúceho kroku RestTemplate a Hystrix. Kvôli jednoduchosti ho budeme nazývať „REST spotrebiteľ“.

Následne vytvoríme nový projekt Maven s štartér na jar-oblak-hystrix, štartér-web na jar a spring-boot-starter-thymeleaf ako závislosti:

 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. UVOĽNENIE 

Aby mohol istič fungovať, Hystix naskenuje @ Komponent alebo @Služba anotované triedy pre @HystixCommand anotované metódy, implementovať proxy server a monitorovať jeho hovory.

Chystáme sa vytvoriť @Služba trieda ako prvá, ktorá bude vpichnutá do a @ Kontrolór. Pretože vytvárame webovú aplikáciu pomocou aplikácie Thymeleaf, potrebujeme ako zobrazenie aj šablónu HTML.

Toto bude náš injekčný prostriedok @Služba vykonávanie a @HystrixCommand s pridruženou záložnou metódou. Táto náhrada musí používať rovnaký podpis ako originál:

@Service verejná trieda GreetingService {@HystrixCommand (fallbackMethod = "defaultGreeting") public String getGreeting (String username) {return new RestTemplate () .getForObject ("// localhost: 9090 / pozdrav / {username}", String.class, meno používateľa ); } private String defaultGreeting (String username) {return "Hello User!"; }}

RestConsumerApplication bude našou hlavnou triedou aplikácií. The @EnableCircuitBreaker anotácia prehľadá cestu ku triede kvôli akejkoľvek kompatibilnej implementácii ističa.

Aby sme mohli Hystrix používať výslovne, musíme túto triedu anotovať @EnableHystrix:

@SpringBootApplication @EnableCircuitBreaker verejná trieda RestConsumerApplication {public static void main (String [] args) {SpringApplication.run (RestConsumerApplication.class, args); }}

Ovládač nastavíme pomocou nášho Pozdravná služba:

@Controller verejná trieda GreetingController {@Autowired private GreetingService greetingService; @GetMapping ("/ get-greeting / {username}") public String getGreeting (Model model, @PathVariable ("username") String username) {model.addAttribute ("pozdrav", pozdravService.getGreeting (meno používateľa)); vrátiť "pozdrav-pohľad"; }}

A tu je šablóna HTML:

   Zdravím Hystrix 

Aby sme zaistili, že aplikácia načúva na definovanom porte, vložili sme do application.properties spis:

server.port = 8080

Ak chcete vidieť istič Hystix v akcii, začíname so svojím zákazníkom a ukazujeme na svoj prehliadač // localhost: 8080 / get-pozdrav / Cid. Za normálnych okolností sa zobrazí toto:

Ahoj Cid!

Aby sme simulovali zlyhanie nášho výrobcu, jednoducho ho zastavíme a po dokončení obnovenia prehliadača by sa mala zobraziť všeobecná správa vrátená z náhradnej metódy v našom @Služba:

Ahoj užívateľ!

4. ODPOČÍTAJTE Spotrebitelia s produktmi Hystrix a Feign

Teraz ideme upraviť projekt z predchádzajúceho kroku tak, aby sme namiesto Spring používali Spring Netflix Feign ako deklaratívneho klienta REST. RestTemplate.

Výhodou je, že sme neskôr schopní ľahko prepracovať naše rozhranie Feign Client tak, aby sme na objavovanie služieb používali Spring Netflix Eureka.

Na začatie nového projektu vytvoríme kópiu nášho spotrebiteľa a pridáme nášho výrobcu a spring-cloud-starter-feign ako závislosti:

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

Teraz môžeme používať našu GreetingController rozšíriť predstieraného klienta. Budeme realizovať Hystrix záložné riešenie ako statická vnútorná trieda s poznámkami @ Komponent.

Prípadne by sme mohli definovať a @Bean komentovaná metóda vracajúca inštanciu tejto záložnej triedy.

Vlastnosť názvu súboru @FeignClient Je povinné. Používa sa na vyhľadanie aplikácie buď vyhľadávaním služby prostredníctvom klienta Eureka, alebo pomocou adresy URL, ak je uvedená táto vlastnosť:

@FeignClient (name = "rest-producer" url = "// localhost: 9090", fallback = GreetingClient.GreetingClientFallback.class) verejné rozhranie GreetingClient rozširuje GreetingController {@Component public static class GreetingClientFallback implementuje GreetingController {@Override public String pozdrav (@ PathVariable ("username") String username) {return "Hello User!"; }}}

Viac informácií o používaní jarnej služby Netflix Eureka na objavovanie služieb nájdete v tomto článku.

V RestConsumerFeignApplication, dáme ďalšiu poznámku, aby sme umožnili Feign integráciu, @EnableFeignClients, do hlavnej triedy aplikácií:

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

Chystáme sa upraviť ovládač tak, aby používal automaticky pripojeného klienta Feign Client, a nie predtým pripojeného @Služba, aby sme získali náš pozdrav:

@Controller verejná trieda GreetingController {@Autowired private GreetingClient greetingClient; @GetMapping ("/ get-greeting / {username}") public String getGreeting (Model model, @PathVariable ("username") String username) {model.addAttribute ("pozdrav", pozdravClient.greeting (meno používateľa)); vrátiť "pozdrav-pohľad"; }}

Aby sme odlíšili tento príklad od predchádzajúceho, zmeníme port na počúvanie aplikácií v priečinku application.properties:

server.port = 8082

Na záver otestujeme tohto spotrebiteľa s povolenou funkciou Feign, ako je ten z predchádzajúcej časti. Očakávaný výsledok by mal byť rovnaký.

5. Cache Fallback With Hystrix

Teraz pridáme Hystrix do nášho projektu Spring Cloud. V tomto cloudovom projekte máme hodnotiacu službu, ktorá komunikuje s databázou a získava hodnotenie kníh.

Predpokladajme, že naša databáza je dopytovaným zdrojom a jeho latencia odozvy sa môže časom líšiť alebo nemusí byť časovo dostupná. Tento scenár zvládneme, keď istič Hystrix Circuit Breaker spadne späť do medzipamäte pre dáta.

5.1. Inštalácia a konfigurácia

Pridajme spring-cloud-starter-hystrix závislosť od nášho hodnotiaceho modulu:

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

Keď sú hodnotenia vložené / aktualizované / vymazané v databáze, replikujeme to isté do vyrovnávacej pamäte Redis pomocou a Úložisko. Ak sa chcete dozvedieť viac informácií o Redise, prečítajte si tento článok.

Poďme aktualizovať Hodnotiaca služba zabaliť metódy dotazovania na databázu do príkazu Hystrix s @HystrixCommand a nakonfigurujte ho na pomoc čítania z Redisu:

@HystrixCommand (commandKey = "RatingsByIdFromDB", fallbackMethod = "findCachedRatingById", ignoreExceptions = {RatingNotFoundException.class}) verejné hodnotenie findRatingById (dlhé hodnotenieId) {návrat Optional.ofNullable (hodnotenieRepository.findOne) nová RatingNotFoundException ("Hodnotenie sa nenašlo. ​​ID:" + hodnotenieId)); } public Rating findCachedRatingById (Long ratingId) {return cacheRepository.findCachedRatingById (ratingId); }

Upozorňujeme, že záložná metóda by mala mať rovnaký podpis ako zabalená metóda a musí sa nachádzať v rovnakej triede. Teraz, keď findRatingById zlyhá alebo sa oneskorí o viac ako stanovený limit, Hystrix sa vráti k findCachedRatingById.

Pretože sú možnosti Hystrixu vkladané transparentne ako rady AOP, musíme upraviť poradie, v akom sú rady zoradené, pre prípad, že by sme mali ďalšie rady, ako napríklad Springova transakčná rada. Tu sme upravili jarnú transakčnú radu AOP tak, aby mala nižšiu prioritu ako rada Hystrix AOP:

@EnableHystrix @EnableTransactionManagement (order = Ordered.LOWEST_PRECEDENCE, mode = AdviceMode.ASPECTJ) public class RatingServiceApplication {@Bean @Primary @Order (value = Ordered.HIGHEST_PRECEDENCE) public HystrixCommandAspect hystrixAspect (hystrixAspect) } // ostatné fazule, konfigurácie}

Tu sme upravili jarné transakčné poradenstvo AOP tak, aby malo nižšiu prioritu ako odporúčanie Hystrix AOP.

5.2. Testovanie riešenia Hystrix Fallback

Teraz, keď sme nakonfigurovali obvod, môžeme ho otestovať spustením databázy H2, s ktorou naše úložisko interaguje. Najprv však spustime inštanciu H2 ako externý proces a nie ako vloženú databázu.

Skopírujme knižnicu H2 (h2-1.4.193.jar) do známeho adresára a spustite server H2:

> java -cp h2-1.4.193.jar org.h2.tools.Server -tcp TCP server bežiaci na tcp: //192.168.99.1: 9092 (iba lokálne pripojenia)

Teraz aktualizujme adresu URL zdroja údajov nášho modulu v hodnotenie-servis.vlastnosti ukázať na tento server H2:

spring.datasource.url = jdbc: h2: tcp: // localhost / ~ / hodnotenie

Naše služby môžeme začať uvádzať v predchádzajúcom článku zo série Spring Cloud a otestovať hodnotenie každej knihy tak, že znížime externú inštanciu H2, ktorú práve prevádzkujeme.

Mohli sme vidieť, že keď nie je k dispozícii databáza H2, Hystrix automaticky spadne späť na Redis, aby prečítal hodnotenie každej knihy. Zdrojový kód demonštrujúci tento prípad použitia nájdete tu.

6. Používanie rozsahov

Normálne a @HytrixCommand komentovaná metóda sa vykonáva v kontexte oblasti vlákien. Niekedy však musí byť spustený v lokálnom rozsahu, napríklad a @SessionScope alebo a @RequestScope. To sa dá urobiť zadaním argumentov do anotácie príkazu:

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

7. Panel Hystrix

Príjemnou voliteľnou funkciou systému Hystrix je schopnosť monitorovať jeho stav na prístrojovej doske.

Aby sme to povolili, uvedieme spring-cloud-starter-hystrix-dashboard a aktivátor pružiny-štartéra-štartéra v pom.xml nášho spotrebiteľa:

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

Prvý je potrebné povoliť prostredníctvom anotácie a @ Konfigurácia s @EnableHystrixDashboard a druhý z nich automaticky umožňuje požadované metriky v našej webovej aplikácii.

Po reštartovaní aplikácie ukážeme na prehliadač // localhost: 8080 / hystrix, zadajte adresu URL metrík streamu Hystrix a začnite monitorovať.

Nakoniec by sme sa mali dočkať niečoho podobného:

Monitorovanie toku Hystrix je niečo v poriadku, ale ak budeme musieť sledovať viac aplikácií s podporou Hystrix, stane sa to nepohodlným. Za týmto účelom poskytuje Spring Cloud nástroj s názvom Turbine, ktorý dokáže agregovať prúdy a prezentovať ich na jednom dashboarde Hystrix.

Konfigurácia Turbine je nad rámec tohto zápisu, tu by sa však mala spomenúť možnosť. Je tiež možné zhromažďovať tieto streamy prostredníctvom správ pomocou toku Turbine.

8. Záver

Ako sme už videli, teraz sme schopní implementovať vzor ističa pomocou Spring Netflix Hystrix spolu s ktorýmkoľvek Spring RestTemplate alebo Spring Netflix Feign.

To znamená, že dokážeme využívať služby so zahrnutou záložnou položkou pomocou predvolených údajov a dokážeme monitorovať využitie týchto údajov.

Ako obvykle, zdroje nájdeme na GitHube.