2017-01-26 206 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'添加前綴的其他服務。 –