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

本文分析了 Spring Cloud Zuul 中路由配置导致的回退失效问题,并给出了具体的解决方案。通过对比不同路由配置和服务转发过滤器,解释了如何通过调整配置启用全局回退。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  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.<init>(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-3ServletDetectionFilter标记处理Servlet的类型
    pre-2Servlet30WrapperFilter包装HttpServletRequest请求
    pre-1FormBodyWrapperFilter包装请求体
    route1DebugFilter标记调试标志
    route5PreDecorationFilter处理请求上下文供后续使用
    route10RibbonRoutingFilterserviceId请求转发
    route100SimpleHostRoutingFilterurl请求转发
    route500SendForwardFilterforward请求转发
    post0SendErrorFilter处理有错误的请求响应
    post1000SendResponseFilter处理正常的请求响应
    由于我的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<String, Object> 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. 附上小弟久违得订阅号,路过的大佬不嫌弃点个关注

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值