首页 > 解决方案 > 通过同一个 API 路由到 Zuul 中的不同服务

问题描述

在我的 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 进行细粒度路由?

标签: restspring-cloudnetflix-eurekanetflix-zuulapi-gateway

解决方案


回答:

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

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

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

  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

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


推荐阅读