Ratpack med Hystrix

1. Introduksjon

Tidligere har vi vist hvordan man bygger en høyytelses- og reaktiv applikasjon med Ratpack.

I denne artikkelen ser vi på hvordan du kan integrere Netflix Hystrix med en Ratpack-applikasjon.

Netflix Hystrix hjelper med å kontrollere interaksjoner mellom distribuerte tjenester ved å isolere tilgangspunkter for å stoppe kaskader og gi tilbakemeldingsmuligheter for feiltoleranse. Det kan hjelpe oss med å bygge en mer elastisk applikasjon. Se introduksjonen til Hystrix for en rask gjennomgang.

Og så, det er slik vi vil bruke det - vi skal forbedre Ratpack-applikasjonen med disse nyttige funksjonene fra Hystrix.

2. Maven avhengighet

For å bruke Hystrix med Ratpack trenger vi ratpack-hystrix-avhengigheten i prosjektet pom.xml:

 io.ratpack ratpack-hystrix 1.4.6 

Den siste versjonen av ratpack-hystrix finner du her. Ratpack-hystrix inkluderer ratpack-core og hystrix-core.

For å bruke reaktive funksjoner i Ratpack, trenger vi også ratpack-rx:

 io.ratpack ratpack-rx 1.4.6 

Den siste versjonen av ratpack-rx finner du her.

3. Servering med Hystrix Command

Når du bruker Hystrix, blir de underliggende tjenestene vanligvis pakket inn i HystrixCommand eller HystrixObservableCommand. Hystrix støtter å utføre disse kommandoene på måter synkront, asynkront og reaktivt. Blant disse er bare reaktive ikke-blokkerende og offisielt anbefalt.

I de følgende eksemplene bygger vi noen endepunkter som henter en profil fra Github REST API.

3.1. Reaktiv kommandoutførelse

La oss først bygge en reaktiv backend-tjeneste med Hystrix:

offentlig klasse HystrixReactiveHttpCommand utvider HystrixObservableCommand {// ... @Override protection Observable construct () {return RxRatpack.observe (httpClient .get (uri, r -> r.headers (h -> h.add ("User-Agent", "Baeldung HttpClient"))) .map (res -> res.getBody (). GetText ())); } @ Override-beskyttet Observable resumeWithFallback () {return Observable.just ("eugenps reaktive reserveprofil"); }}

Her er en Ratpack reaktiv HttpClient brukes til å lage en GET-forespørsel. De HystrixReactiveHttpCommand kan utføre som en reaktiv behandler:

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

Endepunktet kan verifiseres med følgende test:

@Test offentlig ugyldig nårFetchReactive_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("rx"), inneholderString ("www.baeldung.com")); }

3.2. Asynkron kommandokjøring

En asynkron kjøring av HystrixCommand køer kommandoen i trådgruppen og returnerer a Framtid:

chain.get ("async", ctx -> ctx.render (ny HystrixAsyncHttpCommand (eugenGithubProfileUri, timeout) .queue () .get ()));

De HystrixAsyncHttpCommand ser ut som:

offentlig klasse HystrixAsyncHttpCommand utvider HystrixCommand {// ... @Override-beskyttet String run () kaster unntak {return EntityUtils.toString (HttpClientBuilder.create () .setDefaultRequestConfig (requestConfig) .setDefaultHeaders (Collections.singleton) "," Baeldung Blocking HttpClient "))) .build (). Execute (new HttpGet (uri)). GetEntity ()); } @ Override-beskyttet streng getFallback () {returner "eugenps asynk-tilbakefallsprofil"; }}

Her bruker vi en blokkering HttpClient i stedet for en ikke-blokkerende fordi vi vil at Hystrix skal kontrollere utførelsen timeout for den faktiske kommandoen, slik at vi ikke trenger å håndtere det på egenhånd når vi får svar fra Framtid. Dette gjør det også mulig for Hystrix å tilbakestille eller cache vår forespørsel.

Asynkroniseringsutførelsen gir også forventet resultat:

@Test offentlig ugyldig nårFetchAsync_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("async"), inneholderString ("www.baeldung.com")); }

3.3. Synkron kommandoutførelse

En synkron kjøring utfører kommandoen direkte i gjeldende tråd:

chain.get ("sync", ctx -> ctx.render (new HystrixSyncHttpCommand (eugenGithubProfileUri, timeout) .execute ()));

Gjennomføringen av HystrixSyncHttpCommand er nesten identisk med HystrixAsyncHttpCommand bortsett fra at vi gir det et annet tilbakeslagsresultat. Når den ikke faller tilbake, oppfører den seg på samme måte som reaktiv og asynkron kjøring:

@Test offentlig ugyldig nårFetchSync_thenGotEugenProfile () {assertThat (appUnderTest.getHttpClient (). GetText ("sync"), containString ("www.baeldung.com")); }

4. Målinger

Ved å registrere Guice-modulen - HystrixModule i Ratpack-registeret, kan vi streame forespørselens omfang og eksponere hendelsesstrømmene via en sluttpunkt:

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

De HystrixMetricsEventStreamHandler hjelper med å streame Hystrix-beregninger i tekst / event-stream format, slik at vi kan overvåke beregningene i Hystrix Dashboard.

Vi kan sette opp et frittstående Hystrix-dashbord, og legge til vår Hystrix-hendelsesstrøm til skjermlisten for å se hvordan Ratpack-applikasjonen vår utfører:

Etter flere forespørsler til Ratpack-applikasjonen, kan vi se Hystrix-relaterte kommandoer i dashbordet.

4.1. Under panseret

I HystrixModule, er en Hystrix Concurrency Strategy registrert med Hystrix via HystrixPlugin for å administrere forespørselskonteksten med Ratpack-registeret. Dette fjerner nødvendigheten av å initialisere konteksten av Hystrix-forespørsel før hver forespørsel begynner.

offentlig klasse HystrixModule utvider ConfigurableModule {// ... @ Override protected void configure () {try {HystrixPlugins.getInstance (). registerConcurrencyStrategy (new HystrixRegistryBackedConcurrencyStrategy ()); } fange (IllegalStateException e) {// ...}} // ...}

5. Konklusjon

I denne raske artikkelen har vi vist hvordan Hystrix kan integreres i Ratpack, og hvordan du skyver beregninger av Ratpack-applikasjonen til Hystrix Dashboard for bedre oversikt over applikasjonsytelsen.

Som alltid kan full implementering bli funnet på Github-prosjektet.


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