spring cloud zuul 配置全局回退无效的原因

  1. 首先,spring cloud 的版本为 Edgware.SR3
  2. 自定义FallbackProvider 的实现请点击这里,大神写的很详细;
  3. 起初我的bootstrap.yml 配置服务路由为:
    routes:
        auth-server:
          strip-prefix: true
          sensitiveHeaders:
          path: /v1/auth-api/**
          url: http://localhost:8002/
        system-server:
          strip-prefix: true
          sensitiveHeaders:
          path: /v1/system-api/**
          url: http://localhost:8004/
  4. 配置完MyServerFallbackProvider之后启动项目发现回退没生效,还是一直抛异常:com.netflix.zuul.exception.ZuulException:Connect to localhost:8004 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
    at org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException.(ZuulRuntimeException.java:33)
    at org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.run(SimpleHostRoutingFilter.java:207)
    at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112)
    at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193)
    at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157)
    at com.netflix.zuul.FilterProcessor.route(FilterProcessor.java:118)
    at com.netflix.zuul.ZuulRunner.route(ZuulRunner.java:96)
  5. 最终查看源码得知抛出异常而没有回退发现和zull 的默认 filter有关;对zuul 过滤器不了解的小伙伴点击这里,一下为zuul 的默认过滤器
    类型 顺序 过滤器 功能
    pre -3 ServletDetectionFilter 标记处理Servlet的类型
    pre -2 Servlet30WrapperFilter 包装HttpServletRequest请求
    pre -1 FormBodyWrapperFilter 包装请求体
    route 1 DebugFilter 标记调试标志
    route 5 PreDecorationFilter 处理请求上下文供后续使用
    route 10 RibbonRoutingFilter serviceId请求转发
    route 100 SimpleHostRoutingFilter url请求转发
    route 500 SendForwardFilter forward请求转发
    post 0 SendErrorFilter 处理有错误的请求响应
    post 1000 SendResponseFilter 处理正常的请求响应
    由于我的bootstrap.yml 路由配置为 url 形式(上文bootstrap.yml标红的部分) ,所以server 转发filter 为 SimpleHostRoutingFilter,最终通过hettpclient转发到服务端,而SimpleHostRoutingFilter的run()方法中直接抛出了ZuulRuntimeException:
    try {
       CloseableHttpResponse response = forward(this.httpClient, verb, uri, request,
             headers, params, requestEntity);
       setResponse(response);
    }
    catch (Exception ex) {
       throw new ZuulRuntimeException(ex);
    }
    return null;
  6. SimpleHostRoutingFilter的forwardRequest()方法:
    private CloseableHttpResponse forwardRequest(CloseableHttpClient httpclient,
          HttpHost httpHost, HttpRequest httpRequest) throws IOException {
       return httpclient.execute(httpHost, httpRequest);
    }
  7. 至此回退不生效的原因已找到,将bootstrap.yml中服务的路由方式更改为 serviceId形式,默认转发filter为RibbonRoutingFilter
    routes:
      auth-server:
        strip-prefix: true
        sensitiveHeaders:
        path: /v1/auth-api/**
        serviceId: auth-server
      system-server:
        strip-prefix: true
        sensitiveHeaders:
        path: /v1/system-api/**
        serviceId: system-server
  8. RibbonRoutingFilter 中的转发方法:
    protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception {
       Map info = this.helper.debug(context.getMethod(),
             context.getUri(), context.getHeaders(), context.getParams(),
             context.getRequestEntity());
    
       RibbonCommand command = this.ribbonCommandFactory.create(context);
       try {
          ClientHttpResponse response = command.execute();
          this.helper.appendDebug(info, response.getRawStatusCode(), response.getHeaders());
          return response;
       }
       catch (HystrixRuntimeException ex) {
          return handleException(info, ex);
       }
    
    }
  9. RibbonCommand 接口继承了HystrixExecutable,重新启动zuul服务,MyServerFallbackProvider全局回退启用正常了;
  10. 注:随便写写,可能关键点写的不太详细,各位小伙伴如有异议欢迎指正。
  11. 附上小弟久违得订阅号,路过的大佬不嫌弃点个关注

你可能感兴趣的:(spring,cloud,spring,cloud,zuul,配置全局回退不生效)