Spring cloud netflix

@ DTSI

Focus Zuul / hystrix

Rappel architecture

A quoi ça sert ? (1/2)

Zuul

Ou le routage dit "intelligent" en environnements distribués.

 

Plus besoin de savoir où les services sont physiquement installés. Zuul a un double rôle routeur / répartiteur de charge et va s'appuyer sur l'annuaire de services Euréka pour propager les appels de services.

A quoi ça sert ? (2/2)

Ou comment réagir, en environnements distribués, à l'éventuelle indisponibilité d'un ou de plusieurs services tiers.

 

Hystrix est une implémentation du pattern Circuit Breaker. Il s'agit ici de continuer à rendre un service en mode dit dégradé dans vos applications lorsque le service original renvoie un trop grand nombre d'erreurs.

Et si on ne fait rien ?

RAPPEL(s) :

L'utilisation de Zuul est obligatoire lorsque votre application utilise des services tiers (externes à ladite application).

 

Les (micro-) services qui sont utilisés par plus d'une applications doivent obligatoirement s'enregistrer sur l'annuaire de services Euréka.

Première démo

Première démo

Dans un environnement tel que défini à la DTSI (sauf Spring Cloud Config) :

- Spring Boot Admin

- Spring Cloud Netflix Eureka (deux instances répliquées)

 

- Déploiement d'un micro-service exposant le référentiel ISO des pays, et donc référencé dans l'annuaire de service Euréka)

 

- Déploiement d'une application d'inscription : backend Spring Boot et frontend Angular

 

Le projet de démonstration est disponible ici.

Première démo

Comment faire ? (1/3)

Dans l'application utilisatrice de services transverses :

 

Ajouter les dépendances :

        <dependencies>

		(...)

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zuul</artifactId>
		</dependency>

		(...)

	</dependencies>

Comment faire ? (2/3)

Dans l'application utilisatrice de services transverses :

 

Modifier la classe de bootstrap de votre application en lui ajoutant les annotations :


@EnableDiscoveryClient
@EnableZuulProxy

Il y a plusieurs implémentations pour la découverte des services : eureka, consul, zookeeper...

Il est donc possible d'utiliser l'annotation générique @EnableDiscoveryClient (Spring Cloud Commons), ou l'annotation spécifique @EnableEurekaClient (Spring Cloud Netflix).

Comment faire ? (3/3)

Dans l'application utilisatrice de services transverses :

 

Ajouter les éléments de configuration :

eureka:
  client:
    serviceUrl:
      defaultZone: http://vbl-dva-xubuntu15.dev.gnc:10300/eureka/ \
                  ,http://vbl-dva-xubuntu15.dev.gnc:10301/eureka/
    region: dev.gnc
    registerWithEureka: false

zuul:
  ignoredServices: '*'
  routes:
    countries: 
      path: /api/v1/countries/**
      serviceId: MS-Countries
      strip-prefix: false

Et si le service ne repond plus ?

DEUXIEME Démo

- Coupure du service du référentiel ISO 3166 des pays.

- Observation du comportement de l'application.

Que se passe-t'il ?

Troisième démo

- Re-démarrage du référentiel des pays

 

- Re-démarrage de l'application cliente dans une version prenant en charge la protection de l'appel au référentiel des pays

 

- Observation du comportement de l'application

Troisième démo

Que se passe-t'il ?

Mais c'est normal, puisque nous sommes revenus dans la situation d'origine : le service tiers est en fonctionnement...

Et si on coupe de nouveau ledit service ?

Quatrième démo

Comment faire ? (1/3)

Dans l'application utilisatrice de services transverses :

 

Ajouter un Bean de Configuration qui implémente ZuulFallbackProvider.

Attention, ce n'est pas possible pour les versions de Spring - et dépendances associées - inférieures ou égales à Camden.SR1 !

Comment faire ? (2/3)

package nc.dva.examples.hystrix;

import ...;

@Configuration
public class PlayerCountryFallbackConfiguration {

	@Bean
	public ZuulFallbackProvider zuulFallbackProvider() {
		return new ZuulFallbackProvider() {

			@Autowired
			private PlayerRepository lPlayerRepository;

			@Override
			public String getRoute() {
				// Might be confusing: it's the serviceId property and not the
				// route!!!
				// Be carefull !
				return "MS-Countries";
			}

			@Override
			public ClientHttpResponse fallbackResponse() {
				return new ClientHttpResponse() {
					@Override
					public HttpStatus getStatusCode() throws IOException {
						return HttpStatus.OK;
					}

					@Override
					public int getRawStatusCode() throws IOException {
						return HttpStatus.OK.value();
					}

					

Comment faire ? (3/3)

                                        @Override
					public String getStatusText() throws IOException {
						return HttpStatus.OK.toString();
					}

					@Override
					public void close() {
					}

					@Override
					public InputStream getBody() throws IOException {

						List<String> localCountries = lPlayerRepository.findCountries();
						List<Country> result = new ArrayList<Country>();
						
						for (String codeIso3 : localCountries) {
							Country lCountry = new Country(codeIso3, codeIso3);
							result.add(lCountry);
						}

						return new ByteArrayInputStream(new Gson().toJson(result).getBytes());

					}

					@Override
					public HttpHeaders getHeaders() {
						HttpHeaders headers = new HttpHeaders();
						headers.setContentType(MediaType.APPLICATION_JSON);
						headers.setAccessControlAllowOrigin("*");
						return headers;
					}
				};
			}
		};
	}
}
package nc.dva.examples.hystrix;

public class Country {

	private String codeIso3;
	private String libelleCOG;

	(...)

}

HYSTRIX Dashboard

The icing on the cake !

Le résultat est ici assez pauvre, mais le tableau de bord permet, pour chaque service monitoré, de vérifier l'état du circuit - au sens du pattern Circuit  Breaker.

Comment faire ?

Tout se passe dans l'application Spring Boot Admin !

 

Ajouter, dans le fichier pom.xml, la dépendance :


		<dependency>
			<groupId>de.codecentric</groupId>
			<artifactId>spring-boot-admin-server-ui-hystrix</artifactId>
			<version>${spring-boot-admin.version}</version>
		</dependency>

Ajouter, dans le fichier de configuration de l'application :

spring:
  boot:
    admin:
      routes:
        endpoints: env,metrics,trace,dump,jolokia,info,configprops,trace,logfile,refresh, \ 
                   flyway,heapdump,loggers,auditevents,hystrix.stream

Vérification

Sur la page About de Spring Boot Admin : vous devez trouver sba-applications-hystrix dans la liste Loaded ui modules.

Toujours dans Spring Boot Admin, sur la page Détail de l'application concernée, vous devez trouver un nouvel onglet Hystrix qui vous donne accès au tableau de bord Hystrix (cf. copie d'écran supra).

Merci de votre attention

Questions / Débat

Spring cloud Zuul & Hystrix @ DTSI

By Didier Vanderstoken

Spring cloud Zuul & Hystrix @ DTSI

  • 695