【问题标题】:Spring Cloud Zuul fallback serviceSpring Cloud Zuul 后备服务
【发布时间】:2017-11-21 19:12:00
【问题描述】:

是否可以为主服务器/服务器/服务设置代理,但如果不可用,则将请求重定向到辅助服务器/服务器/服务?

辅助服务不是与主服务相同类型的实例。他们的 API 是兼容的,但并不相同。当主要资源不可用时,辅助资源是性能较差的最后一个资源。

我们还没有使用 Eureka,只使用了固定 IP。

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

我查看了ZuulFallbackProvider,但是这个接口是为了在出现错误时提供一个固定的响应。我想,当http://server1:8080/whatever 没有响应时,重定向到http://server2:8080/whateverApi2

谢谢。

【问题讨论】:

    标签: spring spring-cloud netflix-zuul


    【解决方案1】:

    您可以使用ZuulFallbackProvider 做到这一点,但您需要先配置以下内容。

    首先,url-routing - 直接在 zuul.routes.<service>.url 中指定 url - 在 Zuul 中不会在 HystrixCommand 中执行。为此,您需要更改配置,如下所示。

    zuul:
      routes:
        whatever:
          path: /whatever/**
          sensitiveHeaders: Cookie,Set-Cookie
          serviceId: whatever
          stripPrefix: false
    
    ribbon:
      eureka:
        enabled: false
    
    whatever:
      ribbon:
        listOfServers: http://server1:8080/
    

    上面的配置是使用没有eureka的Ribbon。你可以找到详情here

    现在,您的请求将通过 Ribbon 在 HystrixCommand 中执行。所以你可以提供自己的 ZuulFallbackProvider。

    在 ZuulFallbackProvider 中,您可以在 fallbackResponse 方法中向您的 http://server2:8080/whateverApi2. 发出回退请求,如下所示。下面是一个非常幼稚的例子。 :-) 您需要根据自己的目的完成以下示例。

    @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();
                }
            };
        }
    }
    

    【讨论】:

    • 感谢您的回答。我还不会标记为解决方案,只是看看是否有任何“仅配置”替代方案。我将使用您的解决方案,甚至可能在使用完整的 Spring Cloud 基础架构时直接使用 Netflix OSS 组件之一而不是 RestTemplate。
    • 我终于回到了这个问题并尝试了这种方法。但是 ZuulFallbackProvider 是一个静态后备。是否有任何 Zuul、Ribbon 或 Hystrix 可以将请求实际重定向到我的后备服务?我不希望它添加到功能区服务器列表中,因为我希望它作为最后的手段执行,只有在服务器关闭时。
    • 如果您不想使用 hystrix 后备,我认为另一种可能的方法是制作自己的完整 routepost 过滤器。在您的过滤器中,您可以检查原始请求的结果,然后将请求转发到具有适当参数的备用服务器。
    【解决方案2】:

    如果有人尝试做类似的事情,那么真正起作用的是 Hystrix 而不是 Zuul 组件。

    在 Gateway API 中,我们创建一个外观控制器来响应我们想要设置回退解决方案的服务:

    @HystrixCommand(fallbackMethod = "fallbackWhatever")
    @PostMapping
    ResponseEntity<Object> whatever(final RequestEntity<?> request) {
        return defaultClient.searchSubmissions(request.getHeaders(), request.getBody());
    }
    
    ResponseEntity<Object> fallbackWhatever(final RequestEntity<?> request) {
        return fallbackClient.searchSubmissions(request.getHeaders(), request.getBody());
    }
    

    defaultClient 和 fallbackClient 是两个不同的 FeignClient 接口,每个接口都指向每个服务端点。

    就是这样!如果您关闭主服务,网关 API 会开始调用回退服务,而不会返回任何不可用的服务,并且更改只需几毫秒。

    此外,如果您重新打开它,它也会在准备好几毫秒后回复响应。

    【讨论】:

      【解决方案3】:

      需要添加可重试

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

      类似situation

      【讨论】:

        猜你喜欢
        • 2016-10-11
        • 2015-01-18
        • 2015-07-31
        • 2016-03-09
        • 1970-01-01
        • 1970-01-01
        • 2019-05-24
        • 2017-09-19
        • 2018-05-26
        相关资源
        最近更新 更多