Ratpack med Hystrix

1. Introduktion

Tidligere har vi vist, hvordan man bygger en højtydende og reaktiv applikation med Ratpack.

I denne artikel vil vi se på, hvordan man integrerer Netflix Hystrix med en Ratpack-applikation.

Netflix Hystrix hjælper med at kontrollere interaktioner mellem distribuerede tjenester ved at isolere adgangspunkter for at stoppe kaskadefejl og give tilbagefaldsmuligheder for fejltolerance. Det kan hjælpe os med at opbygge en mere robust applikation. Se vores introduktion til Hystrix for en hurtig gennemgang.

Og så, det er sådan, vi bruger det - vi vil forbedre vores Ratpack-applikation med disse nyttige funktioner fra Hystrix.

2. Maven-afhængighed

For at bruge Hystrix med Ratpack har vi brug for ratpack-hystrix-afhængighed i projektet pom.xml:

 io.ratpack ratpack-hystrix 1.4.6 

Den seneste version af ratpack-hystrix kan findes her. Ratpack-hystrix inkluderer ratpack-core og hystrix-core.

For at gøre brug af de reaktive funktioner i Ratpack har vi også brug for ratpack-rx:

 io.ratpack ratpack-rx 1.4.6 

Den seneste version af ratpack-rx kan findes her.

3. Servering med Hystrix Command

Når du bruger Hystrix, er de underliggende tjenester typisk pakket ind i HystrixCommand eller HystrixObservableCommand. Hystrix understøtter udførelse af disse kommandoer på synkrone, asynkrone og reaktive måder. Blandt disse er kun reaktive ikke-blokering og anbefales officielt.

I de følgende eksempler bygger vi nogle slutpunkter, der henter en profil fra Github REST API.

3.1. Reaktiv kommandoudførelse

Lad os først opbygge en reaktiv backend-service med Hystrix:

offentlig klasse HystrixReactiveHttpCommand udvider 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 beskyttet Observable resumeWithFallback () {return Observable.just ("eugenps reaktive reserveprofil"); }}

Her er en Ratpack reaktiv HttpClient bruges til at fremsætte en GET-anmodning. Det HystrixReactiveHttpCommand kan fungere som en reaktiv handler:

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

Slutpunktet kan verificeres med følgende test:

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

3.2. Asynkron kommandoudførelse

En asynkron udførelse af HystrixCommand køer kommandoen i trådpuljen i kø og returnerer a Fremtid:

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

Det HystrixAsyncHttpCommand ligner:

offentlig klasse HystrixAsyncHttpCommand udvider HystrixCommand {// ... @Override beskyttet String run () kaster undtagelse {return EntityUtils.toString (HttpClientBuilder.create () .setDefaultRequestConfig (requestConfig) .setDefaultHeaders (Collections.sealdeader) "," Baeldung Blocking HttpClient "))) .build (). Execute (new HttpGet (uri)). GetEntity ()); } @ Override beskyttet String getFallback () {returner "eugenp's async fallback profile"; }}

Her bruger vi en blokering HttpClient i stedet for en ikke-blokerende, fordi vi ønsker, at Hystrix skal kontrollere udførelsestimeout for den aktuelle kommando, så vi ikke behøver at håndtere det alene, når vi får svar fra Fremtid. Dette gør det også muligt for Hystrix at tilbageføre eller cache vores anmodning.

Asynk-udførelsen giver også forventet resultat:

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

3.3. Synkron udførelse af kommando

En synkron udførelse udfører kommandoen direkte i den aktuelle tråd:

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

Gennemførelsen af HystrixSyncHttpCommand er næsten identisk med HystrixAsyncHttpCommand bortset fra at vi giver det et andet tilbagevendende resultat. Når det ikke falder tilbage, opfører det sig det samme som reaktiv og asynkron udførelse:

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

4. Metrics

Ved at registrere Guice-modulet - HystrixModule i Ratpack-registreringsdatabasen kan vi streame metrics for anmodningsomfanget og eksponere begivenhedsstrømmene via en slutpunkt:

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

Det HystrixMetricsEventStreamHandler hjælper med at streame Hystrix-metrics i tekst / event-stream format, således at vi kan overvåge metrics i Hystrix Dashboard.

Vi kan oprette et enkeltstående Hystrix-dashboard og tilføje vores Hystrix-hændelsesstrøm til skærmlisten for at se, hvordan vores Ratpack-applikation fungerer:

Efter flere anmodninger til vores Ratpack-applikation kan vi se Hystrix-relaterede kommandoer i instrumentbrættet.

4.1. Under kølerhjelmen

I HystrixModule, er en Hystrix Concurrency Strategy registreret hos Hystrix via HystrixPlugin for at administrere anmodningskonteksten med Ratpack-registreringsdatabasen. Dette fjerner nødvendigheden af ​​at initialisere Hystrix-anmodningskonteksten, før hver anmodning begynder.

offentlig klasse HystrixModule udvider ConfigurableModule {// ... @ Override beskyttet ugyldig konfigurere () {prøv {HystrixPlugins.getInstance (). registerConcurrencyStrategy (ny HystrixRegistryBackedConcurrencyStrategy ()); } fange (IllegalStateException e) {// ...}} // ...}

5. Konklusion

I denne hurtige artikel har vi vist, hvordan Hystrix kan integreres i Ratpack, og hvordan man skubber målinger af vores Ratpack-applikation til Hystrix Dashboard for et bedre overblik over applikationsydelsen.

Som altid kan den fulde implementering findes på Github-projektet.


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