通过相同的 API 路由到 Zuul 中的不同服务

Routing to different services in Zuul over the same API

在我的 MicroserviceZoo 中,我有一个 Zuul 网关和 3 个由 Eureka 发现的微服务(service1、service2、service3)。 Zuul 应在外部代表它们并充当 api-具有负载平衡(ribbon)和断路器(hystrix)的网关。

现在在服务路由中,我遇到了一个似乎很容易解决的问题,但我被这个问题困扰的时间太长了。

我想要的是 Zuul 通过相同的路径路由到 service1、service2、service3 API:

gateway:port/api/1/service1/public/time 

应该变成

gateway:port/api/1/public/time

gateway:port/api/1/service2/public/stats

将成为

 gateway:port/api/1/public/stats

..这样 /api/1/public/stats 路由到微服务 2(承载统计方法),/api/1/public/time 路由到微服务 1(承载时间方法)

这是我当前的 Zuul-Config(在 bootstrap.yml 中):

zuul:
  prefix: /api/1
  stripPrefix: false
  routes:
    time:
      path: /**/public/time
      serviceId: service1
    stats:
      path: /**/public/stats
      serviceId: service2
    stream:
      path: /**/public/stream
      serviceId: service3
  ignored-services: '*'
  strip-prefix: false

我错过了什么? 你如何使用 Zuul 和 Eureka 进行细粒度路由?

答案:

正如 Spring Cloud Gateway dev Spencer Gibb 所指出的那样,在 Netflix Zuul 中无法轻松做到这一点

Unfortunately zuul from spring cloud can only strip prefixes. You want rewrite functionality which is only available in spring cloud gateway unless you write your own filter – spencergibb Jul 13 '19 at 20:37

解决方案是切换到 Spring Cloud Gateway,这对于大多数 Zuul 部署来说应该很容易实现。

您可以轻松地单独重写路由,例如:

spring:
  cloud:
    gateway:
     - id: streamservice
          uri: lb://streamservice
          predicates:
            - Path=/stream/**
          filters:
            - RewritePath=/api/(?<streamservice>.*), /$\{streamservice}
     - id: otherservices
          uri: lb://otherservices
          predicates:
            - Path=/otherserviceendpoint
          filters:
            - RewritePath=/api/(?<otherservices>.*), /$\{otherservices}

要实现问题中提出的功能,这意味着网关根本不处理某些服务,请在云网关中定义定位器规则 仅定位服务(通过 Eureka el al 发现服务),在网关 conf.yml:

中包含“isongateway:true”作为元数据
  spring:
      cloud:
        gateway:
          discovery:
            locator:
              include-expression: metadata['isongateway']=='true'
              enabled: true

所以在服务中,应该由网关定位和路由,您将标签添加到 conf.yml:

# this is so we can exclude all services that dont have this metadata in gateway
spring:
  cloud:
    discovery:
      client:
        simple:
          local:
            metadata:
              isongateway: true

...现在所有其他服务都不通过网关路由。