Ratpack met Hystrix

1. Inleiding

Eerder hebben we laten zien hoe je een krachtige en reactieve applicatie kunt bouwen met Ratpack.

In dit artikel zullen we bekijken hoe u Netflix Hystrix kunt integreren met een Ratpack-applicatie.

Netflix Hystrix helpt bij het beheersen van interacties tussen gedistribueerde services door toegangspunten te isoleren om trapsgewijze storingen te stoppen en terugvalopties te bieden voor fouttolerantie. Het kan ons helpen een veerkrachtiger applicatie te bouwen. Zie onze inleiding tot Hystrix voor een snel overzicht.

En dus, zo zullen we het gebruiken - we gaan onze Ratpack-applicatie verbeteren met deze handige functies van Hystrix.

2. Maven Afhankelijkheid

Om Hystrix met Ratpack te gebruiken, hebben we de ratpack-hystrix-afhankelijkheid in het project nodig pom.xml:

 io.ratpack ratpack-hystrix 1.4.6 

De laatste versie van ratpack-hystrix is ​​hier te vinden. De ratpack-hystrix bevat ratpack-core en hystrix-core.

Om gebruik te maken van reactieve functies van Ratpack, hebben we ook ratpack-rx nodig:

 io.ratpack ratpack-rx 1.4.6 

De laatste versie van ratpack-rx is hier te vinden.

3. Dienen met Hystrix Command

Bij gebruik van Hystrix zijn de onderliggende services meestal ingepakt HystrixCommand of Hystrix ObservableCommand. Hystrix ondersteunt het uitvoeren van deze commando's op manieren van synchroon, asynchroon en reactief. Hiervan is alleen reactief niet-blokkerend en officieel aanbevolen.

In de volgende voorbeelden zullen we enkele eindpunten bouwen die een profiel ophalen van Github REST API.

3.1. Reactieve uitvoering van opdrachten

Laten we eerst een reactieve backend-service bouwen met Hystrix:

openbare klasse HystrixReactiveHttpCommand breidt HystrixObservableCommand uit {// ... @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 beschermd Observable resumeWithFallback () {return Observable.just ("eugenp's reactieve terugvalprofiel"); }}

Hier is een Ratpack reactief HttpClient wordt gebruikt om een ​​GET-verzoek te doen. De HystrixReactiveHttpCommand kan presteren als een reactieve handler:

chain.get ("rx", ctx -> nieuwe HystrixReactiveHttpCommand (ctx.get (HttpClient.class), eugenGithubProfileUri, time-out) .toObservable () .subscribe (ctx :: render));

Het eindpunt kan worden geverifieerd met de volgende test:

@Test openbare leegte whenFetchReactive_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("rx"), containsString ("www.baeldung.com")); }

3.2. Asynchrone uitvoering van opdrachten

Een asynchrone uitvoering van HystrixCommand zet de opdracht op de threadpool in de wachtrij en retourneert een Toekomst:

chain.get ("async", ctx -> ctx.render (nieuwe HystrixAsyncHttpCommand (eugenGithubProfileUri, time-out) .queue () .get ()));

De HystrixAsyncHttpCommand lijkt op:

openbare klasse HystrixAsyncHttpCommand breidt HystrixCommand uit {// ... @Override protected String run () genereert uitzondering {return EntityUtils.toString (HttpClientBuilder.create () .setDefaultRequestConfig (requestConfig) .setDefaultHeaders "(New-Collections "," Baeldung HttpClient blokkeren "))) .build (). Execute (nieuwe HttpGet (uri)). GetEntity ()); } @Override beschermde String getFallback () {retourneer "eugenp's asynchrone terugvalprofiel"; }}

Hier gebruiken we een blokkering HttpClient in plaats van een niet-blokkerende omdat we willen dat Hystrix de time-out van de uitvoering van het eigenlijke commando controleert, zodat we het niet alleen hoeven af ​​te handelen wanneer we een antwoord krijgen van de Toekomst. Hierdoor kan Hystrix ook terugvallen of ons verzoek in de cache opslaan.

De asynchrone uitvoering levert ook het verwachte resultaat op:

@Test openbare leegte whenFetchAsync_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("async"), containsString ("www.baeldung.com")); }

3.3. Synchrone uitvoering van opdrachten

Een synchrone uitvoering voert de opdracht rechtstreeks uit in de huidige thread:

chain.get ("sync", ctx -> ctx.render (nieuwe HystrixSyncHttpCommand (eugenGithubProfileUri, time-out) .execute ()));

De implementatie van HystrixSyncHttpCommand is bijna identiek aan HystrixAsyncHttpCommand behalve dat we het een ander terugvalresultaat geven. Als het niet terugvalt, gedraagt ​​het zich hetzelfde als reactieve en asynchrone uitvoering:

@Test openbare leegte whenFetchSync_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("sync"), bevatString ("www.baeldung.com")); }

4. Metrische gegevens

Door de Guice-module te registreren - HystrixModule in het Ratpack-register, kunnen we de metrische gegevens van het aanvraagbereik streamen en de gebeurtenisstromen weergeven via een KRIJGEN eindpunt:

serverSpec.registry (Guice.registry (spec -> spec.module (nieuwe HystrixModule (). sse ()))) .handlers (c -> c.get ("hystrix", nieuwe HystrixMetricsEventStreamHandler ()));

De HystrixMetricsEventStreamHandler helpt bij het streamen van Hystrix-statistieken in tekst / event-stream formaat, zodat we de metrics in Hystrix-dashboard.

We kunnen een stand-alone Hystrix-dashboard opzetten en onze Hystrix-eventstream toevoegen aan de monitorlijst om te zien hoe onze Ratpack-applicatie presteert:

Na verschillende verzoeken aan onze Ratpack-applicatie kunnen we de Hystrix-gerelateerde commando's in het dashboard zien.

4.1. Onder de motorkap

In HystrixModule, is een Hystrix Concurrency Strategy geregistreerd bij Hystrix via HystrixPlugin om de verzoekcontext te beheren met Ratpack registry. Dit neemt de noodzaak weg om de Hystrix-verzoekcontext te initialiseren voordat elk verzoek begint.

openbare klasse HystrixModule breidt ConfigurableModule uit {// ... @Override protected void configure () {probeer {HystrixPlugins.getInstance (). registerConcurrencyStrategy (nieuwe HystrixRegistryBackedConcurrencyStrategy ()); } catch (IllegalStateException e) {// ...}} // ...}

5. Conclusie

In dit korte artikel hebben we laten zien hoe Hystrix kan worden geïntegreerd in Ratpack en hoe je metrics van onze Ratpack-applicatie naar Hystrix Dashboard kunt pushen voor een beter zicht op de applicatieprestaties.

Zoals altijd is de volledige implementatie te vinden op het Github-project.