【问题标题】:Zuul route from root path来自根路径的 Zuul 路由
【发布时间】:2017-06-12 01:00:44
【问题描述】:

我用 Eureka 发现了一些微服务。他们中的大多数都提供了一些 API。 我有名为“网关服务”的“边缘”服务,实际上是 Zuul 代理。 问题是有一个网络应用程序。它由网关服务托管了很长时间,没有任何问题。 但现在我需要将此客户端托管在网关后面的单独服务上。 这不是一个问题。我创建了新服务并将 Web 应用程序放在那里。但问题是网关服务上的 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。但看起来它对根路径没有任何作用,并且仅在与上述任何路由匹配时才运行。

我怎样才能做到这一点?

更新:我在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 e.g.请求服务。 ZuulFilter 对属性中描述的每个请求执行检查,但仅当请求的 URI 以 /api 开头时才会运行,并且它会重定向此请求,就像路径中没有任何 /api 一样。

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

【问题讨论】:

    标签: java spring-boot spring-cloud netflix-zuul


    【解决方案1】:

    我会做以下事情:

    1. 删除zuul.prefix 属性。
    2. 添加 'apito all of yourzuul.routes.*.path` 属性的前缀。
    3. 添加具有以下属性的最终路由(到列表末尾):

    app:
      path: /**
      stripPrefix: false
    

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

    【讨论】:

    • 感谢您的回答。我首先想到的这种解决方案。我完全相信这会奏效。但我认为为每条路由显式编写 /api 前缀有点令人困惑。主要是因为我发布的配置实际上包含 50 多个路由,所以它不够适合我的情况 :) 这个细节我忘了提,我的不好。但这对于有几条路线的代理来说已经足够了。
    • 您可能必须使用 50 多条路线中的大部分/全部,但它会清楚地建议每个服务的确切路线是什么,并且它是一个非常灵活的解决方案,可以支持您尚未提供的其他服务以/api为前缀。
    猜你喜欢
    • 2016-12-23
    • 2017-04-21
    • 2011-08-14
    • 2023-03-30
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    相关资源
    最近更新 更多