Reserva para a rota Zuul

Reserva para a rota Zuul

1. Visão geral

Zuul é um serviço de borda (ou gateway de API) da Netflix que fornece roteamento dinâmico, monitoramento, resiliência e segurança.

Neste tutorial, veremos comoconfigure Zuul routes with fallbacks.

2. Configuração inicial

Para começar, vamos primeiro configurar dois aplicativos Spring Boot. No primeiro aplicativo, criaremos um serviço REST simples. Considerando que, no segundo aplicativo, usaremos o proxy Zuul para criar uma rota para o serviço REST do primeiro aplicativo.

2.1. Um serviço REST simples

Digamos que nosso aplicativo precise exibir as informações meteorológicas de hoje para o usuário. Então, vamos criar um aplicativo de serviço meteorológico baseado em Spring Boot usando o iniciadorspring-boot-starter-web:


    org.springframework.boot
    spring-boot-starter-web

Agora, vamos criar um controlador para nosso serviço meteorológico:

@RestController
@RequestMapping("/weather")
public class WeatherController {

    @GetMapping("/today")
    public String getMessage() {
        return "It's a bright sunny day today!";
    }

}

Agora, vamos executar o serviço meteorológico e verificar a API do serviço meteorológico:

$ curl -s localhost:8080/weather/today
It's a bright sunny day today!

2.2. O aplicativo de gateway de API

Vamos agora criar nosso segundo aplicativo Spring Boot, o API Gateway. Neste aplicativo, criaremos uma rota Zuul para nosso serviço de meteorologia.

E uma vez que tanto nosso serviço meteorológico quanto Zuul desejarão usar 8080 por padrão, vamos configurá-lo para ser executado em uma porta diferente, 7070.

Então, vamos primeiro adicionarspring-cloud-starter-netflix-zuul em pom.xml:


    org.springframework.cloud
    spring-cloud-starter-netflix-zuul

A seguir, adicionaremos a anotação@EnableZuulProxy à nossa classe de aplicativo API Gateway:

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }

}

Finalmente, vamos configurar a rota Zuul, usando Ribbon, para nossa API de serviço meteorológico emapplication.yml:

spring:
   application:
      name: api-gateway
server:
   port: 7070

zuul:
   igoredServices: '*'
   routes:
      weather-service:
         path: /weather/**
         serviceId: weather-service
         strip-prefix: false

ribbon:
   eureka:
      enabled: false

weather-service:
   ribbon:
      listOfServers: localhost:8080

2.3. Testando a rota Zuul

Neste ponto, os dois aplicativos Spring Boot estão configurados para expor a API do serviço meteorológico usando o proxy Zuul.

Então, vamos rodar os aplicativos e verificar a API do serviço meteorológico via Zuul:

$ curl -s localhost:7070/weather/today
It's a bright sunny day today!

2.4. Testando a falha da rota Zuul sem fallback

Agora, vamos parar o aplicativo de serviço meteorológico e verificar o serviço meteorológico via Zuul novamente. Como resultado, veremos uma mensagem de erro na resposta:

$ curl -s localhost:7070/weather/today
{"timestamp":"2019-10-08T12:42:09.479+0000","status":500,
"error":"Internal Server Error","message":"GENERAL"}

Obviamente, essa não é a resposta que o usuário gostaria de ver. Portanto, uma das maneiras de cuidar disso é criar um substituto para a rota Zuul do serviço meteorológico.

3. Zuul Fallback para uma rota

O proxy Zuul usa a Faixa de opções para balanceamento de carga e as solicitações são executadas no comando Hystrix. Como resultado,failures in the Zuul route appear in a Hystrix matrix.

Portanto, para criar um fallback personalizado para uma rota Zuul, criaremos um bean do tipoFallbackProvider.

3.1. A classeWeatherServiceFallback

Neste exemplo, queremos retornar uma mensagem da resposta de fallback em vez da mensagem de erro padrão que vimos anteriormente. Então, vamos criar uma implementação simples deFallbackProvider para a rota de serviço meteorológico:

@Component
class WeatherServiceFallback implements FallbackProvider {

    private static final String DEFAULT_MESSAGE = "Weather information is not available.";

    @Override
    public String getRoute() {
        return "weather-service";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        if (cause instanceof HystrixTimeoutException) {
            return new GatewayClientResponse(HttpStatus.GATEWAY_TIMEOUT, DEFAULT_MESSAGE);
        } else {
            return new GatewayClientResponse(HttpStatus.INTERNAL_SERVER_ERROR, DEFAULT_MESSAGE);
        }
    }

}

Como podemos ver, substituímos os métodosgetRouteefallbackResponse. The getRoute method returns the Id of the route para o qual temos que criar o fallback. Considerando que,the fallbackResponse method returns the custom fallback response, um objeto do tipoGatewayClientResponse em nosso caso. OGatewayClientResponse é uma implementação simples deClientHttpResponse.

3.2. Testando o Zuul Fallback

Vamos agora testar o substituto que criamos para o serviço de meteorologia. Portanto, vamos executar o aplicativo API Gateway e garantir que o aplicativo de serviço meteorológico esteja parado.

Agora, vamos acessar a API de serviço meteorológico por meio da rota Zuul e ver a resposta alternativa em ação:

$ curl -s localhost:7070/weather/today
Weather information is not available.

4. Fallback para todas as rotas

Até agora, vimos como criar um substituto para uma rota Zuul usando sua rotaId. No entanto, vamos supor que também desejamoscreate a generic fallback for all other routes em nosso aplicativo. Podemos fazer isso criando mais uma implementação deFallbackProviderereturning * or null from the getRoute method, em vez da rotaId:

@Override
public String getRoute() {
    return "*"; // or return null;
}

5. Conclusão

Neste tutorial, vimos um exemplo de criação de um substituto para uma rota Zuul. Também vimos como podemos criar um substituto genérico para todas as rotas Zuul.

Como de costume, a implementação de todos esses exemplos e trechos de código pode ser encontradaover on GitHub.