2017-01-26 155 views
7

我有一些与尤里卡发现的微服务。他们大多提供一些API。 实际上,作为Zuul Proxy的“边缘”服务被称为“网关服务”。 事情是有一个Web应用程序。它由网关服务主持了很长时间,并没有任何问题。 但现在我需要在网关后面的单独服务中托管此客户端。 这不是问题。我创建了新的服务并将Web应用程序放在那里。但事实是,Zuul在网关服务有一个配置从根路径Zuul路线

zuul: 
    ignoredServices: '*' 
    prefix: /api 
    sensitiveHeaders: Cookie, Set-Cookie 
    routes: 
    config-service: 
     path: /conf/** 
     serviceId: config-service 
    security-service: 
     path: /security/** 
     serviceId: security-service 
     stripPrefix: false 
    request-service: 
     path: /requests/** 
     stripPrefix: false 

我必须这样做能够从这样一个http://app.com/根路径访问Web应用中的用户。 但现在我只能通过http://app.com/api/访问它,这是完全不正确的。

我的任务是:托管在从根路径的另一个服务

  1. 使Web应用程序。
  2. /api前缀对所有其他服务保留也很重要。

我试图执行ZuulFilter。但看起来它对根路径没有任何作用,只有在与上述任何路由匹配时才会运行。

我该如何做这项工作?

UPDATE:我有一点成功ZuulFilter。我做到了。这里是Zuul的配置:

zuul: 
    ignoredServices: '*' 
    sensitiveHeaders: Cookie, Set-Cookie 
    routes: 
    api: /api/** 
    config-service: 
     path: /conf/** 
     serviceId: config-service 
    security-service: 
     path: /security/** 
     serviceId: security-service 
     stripPrefix: false 
    request-service: 
     path: /requests/** 
     stripPrefix: false 
    frontend-host-service: 
     path: /** 

而且ZuulFilter本身

@Bean 
    public ZuulFilter apiPrefixStrip(RouteLocator routeLocator) { 
     return new ZuulFilter() { 

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

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

      @Override 
      public boolean shouldFilter() { 
       RequestContext context = RequestContext.getCurrentContext(); 
       return context.getRequest().getRequestURI().startsWith("/api"); 
      } 

      @Override 
      public Object run() { 
       RequestContext context = RequestContext.getCurrentContext(); 
       String path = context.getRequest().getRequestURI(); 
       Route route = routeLocator.getMatchingRoute(path.substring(4)); 
       if (route != null) { 
        context.put("proxy",route.getId()); 
        context.put("requestURI", route.getPath()); 
        context.set("serviceId", route.getLocation()); 
       } 
       return null; 
      } 
     }; 
    } 

这项工作如何: 有物业zuul.routes.api=/api/**它不会做任何事情其实。它只允许将所有匹配的路径映射到Zuul滤波器链(described in documentation)。这里描述的所有其他路线的设置就像根本没有/api一样。它允许达到这样的服务:例如http://app.com/requests为请求服务。 ZuulFilter会执行对属性中描述的每个请求的检查,但只有在请求的URI以/api开头并且它会像路径中没有任何/api一样重定向此请求时才会运行。

它确实有效。但我仍然不喜欢这个解决方案,因为没有/api前缀的端点仍然保留在网关服务上。可能有人知道如何改进它?

回答

3

我会做到以下几点:

  1. 删除该zuul.prefix财产。
  2. 预先加上'api to all of your zuul.routes。*。path`属性的前缀。
  3. 添加的最终路线(名单的末尾),其具有以下特性:

app: 
    path: /** 
    stripPrefix: false 

(3)是路由的顺序这里重要的非常重要的。这是传入请求将评估路由是否匹配的顺序。在yaml中执行此操作也很重要,因为订单将保留下来,可能不会包含属性文件(根据documentation)。

+0

谢谢你的回答。我首先想到这种解决方案。而且我完全确信这会起作用。但我认为为每条路线明确写入'''/ api''前缀有点令人困惑。主要是因为我发布的配置实际上包含50多条路线,所以它不适合我的情况:)这个细节我忘了提及,我的不好。但是这对于有几条路线的代理来说足够好。 –

+1

您可能需要50条以上的路线中的大部分/全部,但它会清楚地说明每条服务的确切路线,并且它是一个非常灵活的解决方案,可用于支持尚未用'/ api'添加前缀的其他服务。 –