根据查询参数动态更改Zuul中路线的url

时间:2019-05-21 14:05:23

标签: java spring-cloud netflix-zuul

正如标题所示,我想根据给定的查询参数更改网址。例如,如果我请求:

  • http://api.company.com/path?service=A >>路由到上游A
  • http://api.company.com/path?service=B >>路由到上游B

我尝试了基于thisthisthisthat的多个不同版本。这些示例都不起作用,也不提供完整的列表环境(代码+配置文件)。

当前无效版本:

application.yml:

zuul:
  ignoredServices: '*'
  routes:
    serviceA:
      path: /statistics/**
      url: http://localhost:3000/a
    serviceB:
      path: /statistics/**
      url: http://localhost:3000/b

Zuul的PreFilter

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

import java.net.URL;

import static com.netflix.zuul.context.RequestContext.getCurrentContext;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.*;


public class QueryParamServiceIdPreFilter extends ZuulFilter {

    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER + 1;
    }

    public String filterType() {
        return PRE_TYPE;
    }

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

    public Object run() {
        RequestContext ctx = getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        // always null
        URL routeHost = getCurrentContext().getRouteHost();

        if ( "A".equals(request.getParameter("serviceUrl")) ) {
            ctx.put("serviceId", "serviceA");
        }

        if ( "B".equals(request.getParameter("serviceUrl")) ) {
            ctx.put("serviceId", "serviceB");
        }

        return null;
    }
}

假微服务:

var express = require('express');
var app = express();
app.get('/a', function (req, res) {
  res.send('Service A');
});

app.get('/b', function (req, res) {
  res.send('Service B');
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

通话结果

$ curl "localhost:8071/statistics?serviceUrl=B" ;  echo; curl "localhost:8071/statistics?serviceUrl=A"
Service B
Service B⏎

1 个答案:

答案 0 :(得分:1)

您的代码看起来不错,您缺少的是服务发现。 你说:

ctx.put("serviceId", "serviceA");

但是您没有定义服务ID,而是在这里使用服务网址:

serviceA:
  path: /statistics/**
  url: http://localhost:3000/a

配置服务发现后,您将拥有:

serviceA:
  path: /statistics/**
  serviceId: serviceA

检查我的答案herehere