Ratpack avec Hystrix

1. Introduction

Auparavant, nous avons montré comment construire une application performante et réactive avec Ratpack.

Dans cet article, nous verrons comment intégrer Netflix Hystrix à une application Ratpack.

Netflix Hystrix aide à contrôler les interactions entre les services distribués en isolant les points d'accès pour arrêter les échecs en cascade et en fournissant des options de secours pour la tolérance aux pannes. Cela peut nous aider à créer une application plus résiliente. Consultez notre introduction à Hystrix pour un examen rapide.

Et c'est ainsi que nous allons l'utiliser - nous allons améliorer notre application Ratpack avec ces fonctionnalités utiles de Hystrix.

2. Dépendance de Maven

Pour utiliser Hystrix avec Ratpack, nous avons besoin de la dépendance ratpack-hystrix dans le projet pom.xml :

 io.ratpack ratpack-hystrix 1.4.6 

La dernière version de ratpack-hystrix peut être trouvée ici. Le ratpack-hystrix comprend ratpack-core et hystrix-core.

Pour utiliser les fonctionnalités réactives de Ratpack, nous aurions également besoin de ratpack-rx:

 io.ratpack ratpack-rx 1.4.6 

La dernière version de ratpack-rx peut être trouvée ici.

3. Servir avec Hystrix Command

Lorsque vous utilisez Hystrix, les services sous-jacents sont généralement encapsulés dans HystrixCommand ou HystrixObservableCommand . Hystrix prend en charge l'exécution de ces commandes de manière synchrone, asynchrone et réactive. Parmi ceux-ci, seul le réactif est non bloquant et officiellement recommandé.

Dans les exemples suivants, nous allons créer des points de terminaison qui récupèrent un profil depuis l'API REST Github.

3.1. Exécution de commande réactive

Tout d'abord, construisons un service backend réactif avec Hystrix:

public class HystrixReactiveHttpCommand extends 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("eugenp's reactive fallback profile"); } }

Ici, un HttpClient réactif Ratpack est utilisé pour faire une requête GET. Le HystrixReactiveHttpCommand peut fonctionner comme un gestionnaire réactif:

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

Le point final peut être vérifié avec le test suivant:

@Test public void whenFetchReactive_thenGotEugenProfile() { assertThat(appUnderTest.getHttpClient().getText("rx"), containsString("www.baeldung.com")); }

3.2. Exécution de commande asynchrone

Une exécution asynchrone de HystrixCommand met la commande en file d'attente sur le pool de threads et renvoie un Future :

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

Le HystrixAsyncHttpCommand ressemble à:

public class HystrixAsyncHttpCommand extends HystrixCommand { //... @Override protected String run() throws Exception { return EntityUtils.toString(HttpClientBuilder.create() .setDefaultRequestConfig(requestConfig) .setDefaultHeaders(Collections.singleton( new BasicHeader("User-Agent", "Baeldung Blocking HttpClient"))) .build().execute(new HttpGet(uri)).getEntity()); } @Override protected String getFallback() { return "eugenp's async fallback profile"; } }

Ici, nous utilisons un HttpClient bloquant au lieu d'un non bloquant car nous voulons qu'Hystrix contrôle le délai d'exécution de la commande réelle afin que nous n'ayons pas besoin de le gérer nous-mêmes lors de l'obtention d'une réponse du Future . Cela permet également à Hystrix de se replier ou de mettre en cache notre demande.

L'exécution asynchrone produit également le résultat attendu:

@Test public void whenFetchAsync_thenGotEugenProfile() { assertThat(appUnderTest.getHttpClient().getText("async"), containsString("www.baeldung.com")); }

3.3. Exécution de commande synchrone

Une exécution synchrone exécute la commande directement dans le thread courant:

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

L'implémentation de HystrixSyncHttpCommand est presque identique à HystrixAsyncHttpCommand sauf que nous lui donnons un résultat de repli différent. Lorsqu'il ne recule pas, il se comporte de la même manière que l'exécution réactive et asynchrone:

@Test public void whenFetchSync_thenGotEugenProfile() { assertThat(appUnderTest.getHttpClient().getText("sync"), containsString("www.baeldung.com")); }

4. Mesures

En enregistrant le module Guice - HystrixModule dans le registre Ratpack, nous pouvons diffuser les métriques de portée de la demande et exposer les flux d'événements via un point de terminaison GET :

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

Le HystrixMetricsEventStreamHandler aide flux métriques Hystrix dans le texte / flux d'événements format, tel que nous pouvons surveiller les paramètres dans Dashboard Hystrix .

Nous pouvons configurer un tableau de bord Hystrix autonome et ajouter notre flux d'événements Hystrix à la liste des moniteurs pour voir comment notre application Ratpack fonctionne:

Après plusieurs requêtes à notre application Ratpack, nous pouvons voir les commandes liées à Hystrix dans le tableau de bord.

4.1. Sous la capuche

Dans HystrixModule , une stratégie de concurrence Hystrix est enregistrée avec Hystrix via HystrixPlugin pour gérer le contexte de demande avec le registre Ratpack. Cela supprime la nécessité d'initialiser le contexte de requête Hystrix avant le début de chaque requête.

public class HystrixModule extends ConfigurableModule { //... @Override protected void configure() { try { HystrixPlugins.getInstance().registerConcurrencyStrategy( new HystrixRegistryBackedConcurrencyStrategy()); } catch (IllegalStateException e) { //... } } //... }

5. Conclusion

Dans cet article rapide, nous avons montré comment Hystrix peut être intégré dans Ratpack et comment pousser les métriques de notre application Ratpack vers Hystrix Dashboard pour une meilleure vue des performances de l'application.

Comme toujours, l'implémentation complète peut être trouvée sur le projet Github.