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

Posted

技术标签:

【中文标题】通过同一个 API 路由到 Zuul 中的不同服务【英文标题】:Routing to different services in Zuul over the same API 【发布时间】:2019-11-23 02:20:08 【问题描述】:

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

现在在服务路由中,我遇到了一个看起来很容易解决的问题,但我被这个问题困扰太久了。

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

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 路由到 microservice2(托管 stats 方法)和 /api/1/public/time 路由到 microservice1(托管 time 方法)

这是我当前的 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的zuul只能去除前缀。除非您编写自己的过滤器,否则您需要仅在 Spring Cloud Gateway 中可用的重写功能 谢谢你的好提示@spencergibb 你会建议迁移到spring cloud gateway还是自己实现一个过滤器?我认为云网关可能更适合未来,因为它成功了 zuul..? 【参考方案1】:

答案:

正如 Spring Cloud Gateway 开发人员 Spencer Gibb 所指出的,在 Netflix Zuul 中没有办法轻松做到这一点

不幸的是 spring cloud 的 zuul 只能去除前缀。您想要重写功能,除非您编写自己的过滤器,否则只能在 Spring Cloud Gateway 中使用 – spencergibb 2019-07-13 20:37:07

解决方案是切换到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

为了实现问题中提出的功能,这意味着某些服务根本不被网关处理,在云网关中定义了一个定位器规则 仅在网关 conf.yml 中定位包含“isongateway:true”作为元数据的服务(通过 Eureka el al 发现服务):

  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

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

【讨论】:

以上是关于通过同一个 API 路由到 Zuul 中的不同服务的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud微服务(05):Zuul组件,实现路由网关控制

SpringCloud微服务(05):Zuul组件,实现路由网关控制

路由网关Zuul之一

SpringCloud系列研究---服务网关zuul

使用zuul路由到docker中的不同容器不起作用

spring cloud连载第三篇补充之Zuul