如何在 zuul/ribbon 中获取将请求转发到的服务器的主机名

How to get the hostname of the server to which a request will be forwarded to in zuul/ribbon

我目前分别使用 Zuul 和 Ribbon 作为反向代理和负载均衡器。我还使用 Eureka 作为服务发现。我在 Eureka 中有多个服务实例,我想知道 Ribbon 选择的服务器的主机名。

这是我当前的配置:

GatewayApplication.java:

@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
  static RequestQueue q = new RequestQueue();

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

  @Bean
  public LogIncomingRequest logIncomingRequest() {
    return new LogIncomingRequest(q);
  }

  @Bean
  public LogLeavingRequest logLeavingRequest() {
    return new LogLeavingRequest(q);
  }
}

application.yml:

server:
  port: 4000

spring:
  application:
    name: zuul-gateway

zuul:
  sensitive-headers:

eureka:
  client:
    serviceUrl:
      defaultZone: http://${EUREKA:10.0.2.15:8761}/eureka/
    register-with-eureka: true
    fetch-registry: true
  instance:
    prefer-ip-address: true

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 60000

我还有一个前置过滤器和一个 post 过滤器。如何获取有关功能区选择的服务器的信息?

我找到了这段代码,但我不知道在哪里使用它以及如何访问这些信息。

@Component
public class RibbonInterceptor extends ZoneAvoidanceRule {

@Override
public Server choose(Object key) {
  Server choose = super.choose(key);
  System.out.println(choose);
  return choose;
}

还有其他解决办法吗?

提前致谢!

在你的 zuul api 网关中实现一个 "pre" 过滤器,如果你看一下 zuul 的 PreDecorationFilter,你会看到它根据提供的内容确定路由的位置和方式。还为下游请求

设置各种代理相关headers

在您的过滤器 运行 方法中

context = RequestContext.getCurrentContext();    
request = context.getRequest();

在上下文中调用 getRouteHost 方法object 它将为您提供所有与路由相关的信息,如协议、主机、端口等。

RequestContext.getCurrentContext().getRouteHost();

注意:过滤器的阶数应大于 5,因为 preDecorationFilter 的阶数为 5

@Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER;
    }

我刚刚找到了解决问题的方法。我创建了一个 POST 过滤器,并使用以下代码获得了我需要的信息:

RequestContext ctx = RequestContext.getCurrentContext();
((IResponse) ctx.get("ribbonResponse")).getRequestedURI();

Fábio Pina 发布的解决方案非常适合我。这是我用于记录的内容:

@Component
public class ZuulLoggingFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();

        RequestContext ctx = RequestContext.getCurrentContext();

        logger.info("********************************************************");
        logger.info("RequestedURI -> {}", ((IResponse) ctx.get("ribbonResponse")).getRequestedURI());
        logger.info("********************************************************");

        return null;
    }

    @Override
    public String filterType() {
        return "post";
    }

    @Override
    public int filterOrder() {
        return 1;
    }

}