Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Cloud Zuul fallback service

Is it possible to setup a proxy to a main server/servers/service but when this is not available, redirect requests to a secondary server/servers/service?

The secondary service is not an instance of the same type of the primary one. Their API is compatible but not the same. The secondary is a less-performant last resource when the primary is not available.

We are not using Eureka, only fixed IPs yet.

zuul:
  routes:
    whatever:
      path: /whatever/**
      sensitiveHeaders: Cookie,Set-Cookie
      url: http://server1:8080/whatever

I had a look on ZuulFallbackProvider, but this interface is to provided a fixed response on case of error. I want, when http://server1:8080/whatever is not responding, redirect to http://server2:8080/whateverApi2.

Thanks.

like image 476
Ricardo Piccoli Avatar asked Dec 24 '22 17:12

Ricardo Piccoli


1 Answers

You can do that with ZuulFallbackProvider, but you need to configure the below first.

First, url-routing - specifying url directly in zuul.routes.<service>.url - in Zuul is NOT executed in HystrixCommand. To achieve this, you need to change your configuration like the below.

zuul:
  routes:
    whatever:
      path: /whatever/**
      sensitiveHeaders: Cookie,Set-Cookie
      serviceId: whatever
      stripPrefix: false

ribbon:
  eureka:
    enabled: false

whatever:
  ribbon:
    listOfServers: http://server1:8080/

The above configuration is using Ribbon without eureka. You can find the detais here

Now, your request will be executed in HystrixCommand via Ribbon. So you can provide your own ZuulFallbackProvider.

In ZuulFallbackProvider, you can make your fallback request to your http://server2:8080/whateverApi2. in fallbackResponse method like below. The below is a very naive example. :-) You need to complete the below example for your own purpose.

@Component
public class TestZuulFallbackProvider implements ZuulFallbackProvider{
    @Override
    public String getRoute() {
        return "test";
    }

    @Override
    public ClientHttpResponse fallbackResponse() {

        ResponseEntity<String> response = new RestTemplate().exchange("http://server2:8080/whateverApi2", HttpMethod.GET, null, String.class);
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return response.getStatusCode();
            }
            @Override
            public int getRawStatusCode() throws IOException {
                return response.getStatusCodeValue();
            }
            @Override
            public String getStatusText() throws IOException {
                return response.getStatusCode().getReasonPhrase();
            }
            @Override
            public void close() {
            }
            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(response.getBody().getBytes("UTF-8"));
            }
            @Override
            public HttpHeaders getHeaders() {
                return response.getHeaders();
            }
        };
    }
}
like image 144
yongsung.yoon Avatar answered Dec 28 '22 08:12

yongsung.yoon