Ratpack s Hystrixom
1. Uvod
Prethodno smo pokazali kako s Ratpackom izraditi aplikaciju visokih performansi i reaktivnu aplikaciju.
U ovom ćemo članku pogledati kako integrirati Netflix Hystrix s aplikacijom Ratpack.
Netflix Hystrix pomaže u kontroli interakcija između distribuiranih usluga izoliranjem pristupnih točaka za zaustavljanje kaskadnih kvarova i pružanjem zamjenskih opcija za toleranciju kvarova. Može nam pomoći u izgradnji otpornije aplikacije. Pogledajte naš uvod u Hystrix za brzi pregled.
I tako ćemo ga koristiti - poboljšat ćemo našu aplikaciju Ratpack s ovim korisnim značajkama koje nudi Hystrix.
2. Ovisnost Mavena
Da bismo koristili Hystrix s Ratpackom, potrebna nam je ovisnost ratpack-hystrix u projektu pom.xml:
io.ratpack ratpack-hystrix 1.4.6
Najnoviju verziju ratpack-hystrixa možete pronaći ovdje. Ratpack-hystrix uključuje jezgru ratpack-a i hystrix-core.
Da bismo iskoristili reaktivne značajke Ratpacka, trebat će nam i ratpack-rx:
io.ratpack ratpack-rx 1.4.6
Najnoviju verziju ratpack-rx možete pronaći ovdje.
3. Posluživanje s Hystrix naredbom
Kada se koristi Hystrix, temeljne su usluge obično umotane HystrixCommand ili HystrixObservableCommand. Hystrix podržava izvršavanje ovih naredbi na sinhroni, asinkroni i reaktivni način. Među njima je samo reaktivni neblokirajući i službeno preporučen.
U sljedećim ćemo primjerima izgraditi neke krajnje točke koje dohvaćaju profil iz Github REST API-ja.
3.1. Izvršenje reaktivne naredbe
Prvo, izgradimo reaktivnu pozadinsku uslugu s Hystrixom:
javna klasa HystrixReactiveHttpCommand proširuje HystrixObservableCommand {// ... @Override protected Observable construct () {return RxRatpack.observe (httpClient .get (uri, r -> r.headers (h -> h.add ("User-Agent", "Baeldung HttpClient"))) .map (res -> res.getBody (). GetText ())); } @Override protected Observable resumeWithFallback () {return Observable.just ("eugenpov reaktivni rezervni profil"); }}
Ovdje je Ratpack reaktivan HttpClient koristi se za izradu GET zahtjeva. The HystrixReactiveHttpCommand može nastupiti kao reaktivni rukovatelj:
chain.get ("rx", ctx -> novi HystrixReactiveHttpCommand (ctx.get (HttpClient.class), eugenGithubProfileUri, timeout) .toObservable () .subscribe (ctx :: render));
Krajnja se točka može provjeriti sljedećim testom:
@Test public void whenFetchReactive_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("rx"), containsString ("www.baeldung.com")); }
3.2. Asinkrono izvršenje naredbe
Asinkrono izvršavanje HystrixCommand postavlja naredbu u spremište niti i vraća a Budućnost:
chain.get ("async", ctx -> ctx.render (novi HystrixAsyncHttpCommand (eugenGithubProfileUri, timeout) .queue () .get ()));
The HystrixAsyncHttpCommand izgleda kao:
javna klasa HystrixAsyncHttpCommand proširuje HystrixCommand {// ... @Override zaštićeni niz run () baca izuzetak {return EntityUtils.toString (HttpClientBuilder.create () .setDefaultRequestConfig (requestConfig) .setDefaultHeaderent (User Basic) "," Baeldung blokira HttpClient "))). Build (). Execute (novi HttpGet (uri)). GetEntity ()); } @Override zaštićeni niz getFallback () {return "eugenpov async rezervni profil"; }}
Ovdje koristimo blokiranje HttpClient umjesto neblokirajuće jer želimo da Hystrix kontrolira vremensko ograničenje izvršavanja stvarne naredbe, tako da nećemo morati samostalno postupati s njom kad dobijemo odgovor od Budućnost. To također omogućava Hystrixu da izvrši zamjenski ili kešira naš zahtjev.
Izvršenje asinkronizacije također donosi očekivani ishod:
@Test public void whenFetchAsync_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("async"), containsString ("www.baeldung.com")); }
3.3. Sinkrono izvršavanje naredbi
Sinkrono izvršavanje izvršava naredbu izravno u trenutnoj niti:
chain.get ("sync", ctx -> ctx.render (novi HystrixSyncHttpCommand (eugenGithubProfileUri, timeout) .execute ()));
Provedba HystrixSyncHttpCommand je gotovo identičan HystrixAsyncHttpCommand osim što mu dajemo drugačiji povratni rezultat. Kad se ne povuče, ponaša se jednako kao reaktivno i asinkrono izvršavanje:
@Test public void whenFetchSync_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("sync"), containsString ("www.baeldung.com")); }
4. Metrika
Registracijom Guice modula - HystrixModule u registar Ratpack, možemo strujati mjerne podatke s opsegom zahtjeva i izlagati tokove događaja putem a DOBITI krajnja točka:
serverSpec.registry (Guice.registry (spec -> spec.module (new HystrixModule (). sse ()))) .handlers (c -> c.get ("hystrix", new HystrixMetricsEventStreamHandler ()));
The HystrixMetricsEventStreamHandler pomaže u strujanju Hystrixove metrike u sustavu Windows tekst / tok-događaja formatu, tako da možemo pratiti mjerne podatke u Hystrix nadzorna ploča.
Možemo postaviti samostalnu nadzornu ploču Hystrix i dodati naš tok događaja Hystrix na popis monitora kako bismo vidjeli kako funkcionira naša aplikacija Ratpack:
Nakon nekoliko zahtjeva za našu aplikaciju Ratpack, na nadzornoj ploči možemo vidjeti naredbe povezane s Hystrixom.
4.1. Ispod haube
U HystrixModule, Hystrix strategija istodobnosti registrirana je kod Hystrixa putem HystrixPlugina za upravljanje kontekstom zahtjeva s registrom Ratpack. Ovo uklanja potrebu za inicijalizacijom konteksta zahtjeva Hystrix prije nego što svaki zahtjev započne.
javna klasa HystrixModule proširuje ConfigurableModule {// ... @Override protected void configure () {try {HystrixPlugins.getInstance (). registerConcurrencyStrategy (new HystrixRegistryBackedConcurrencyStrategy ()); } catch (IllegalStateException e) {// ...}} // ...}
5. Zaključak
U ovom kratkom članku pokazali smo kako se Hystrix može integrirati u Ratpack i kako gurnuti metrike naše aplikacije Ratpack na Hystrix nadzornu ploču radi boljeg prikaza performansi aplikacije.
Kao i uvijek, potpuna implementacija može se naći na projektu Github.