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

时间:2018-05-24 15:27:04

标签: java spring-cloud netflix-zuul spring-cloud-netflix netflix-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

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

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

@Component
public class RibbonInterceptor extends ZoneAvoidanceRule {

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

还有其他解决方案吗?

提前致谢!

3 个答案:

答案 0 :(得分:1)

实施" pre"在你的zuul api网关中过滤,如果你看一下zuul的PreDecorationFilter,你会看到它根据提供的内容确定路由的位置和方式。还为下游请求设置各种代理相关的标头

在过滤器运行方法

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

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

RequestContext.getCurrentContext().getRouteHost();

注意:过滤器的顺序应为> 5,因为preDecorationFilter的顺序为5

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

答案 1 :(得分:1)

我只是设法为我的问题找到解决方案。我创建了一个POST过滤器,我使用此代码获得了所需的信息:

select id, IdCust, Ref,
       max(case when Seq = 1 then stock end) as [Stock A], -- second table *id*
       max(case when Seq = 1 then code end) as [Code 1],
       max(case when Seq = 1 then price end) as [Price1],
       max(case when Seq = 2 then stock end) as [Stock B], -- second table *id*
       max(case when Seq = 2 then code end) as [Code 2],
       max(case when Seq = 2 then price end) as [Price2]
from (select f.*, s.Id Stock, s.Code, s.Price,
             row_number() over (partition by f.Ref order by s.id) as Seq
     from first f
     inner join second s on s.Ref = f.Ref 
     ) t
group by id, IdCust, Ref;

答案 2 :(得分:0)

FábioPina发布的解决方案仅对我有用。这是我用于记录的内容:

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

}