1

I'm currently using Zuul and Ribbon as a reverse proxy and load balancer respectively. I'm also using Eureka as service discovery. I have more than one instance of a service in Eureka, and I want to know the hostname of the server chosen by Ribbon.

This is my current configuration:

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

I also have a pre and a post filter. How can I get the information about the server that was chosen by ribbon?

I found this code but I have no idea where to use it and how to access the information.

@Component
public class RibbonInterceptor extends ZoneAvoidanceRule {

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

Are there any other solutions?

Thanks in advance!

anothernode
  • 5,100
  • 13
  • 43
  • 62
Fábio Pina
  • 63
  • 10

3 Answers3

1

Implement a "pre" filter in your zuul api gateway, if you have a look at PreDecorationFilter of zuul, you will see that it determines where and how to route based on the supplied. Also sets various proxy related headers for downstream requests

in your filters run method

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

call the getRouteHost method on context object it will give you all the route related information like protocol, host, port etc..

RequestContext.getCurrentContext().getRouteHost();

NOTE: the order of your filter should be > 5, since preDecorationFilter has order of 5

@Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER;
    }
jayant mishra
  • 686
  • 5
  • 13
1

I just managed to find a solution for my problem. I created a POST filter and i got the information i needed using this code:

RequestContext ctx = RequestContext.getCurrentContext();
((IResponse) ctx.get("ribbonResponse")).getRequestedURI();
Fábio Pina
  • 63
  • 10
0

The solution that Fábio Pina posted just works for me. Here is what I'm using for logging:

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

}
Carlos Cruz
  • 405
  • 3
  • 6