【问题标题】:How to rewrite serviceId for Spring Cloud Gateway with service discovery如何使用服务发现重写 Spring Cloud Gateway 的 serviceId
【发布时间】:2020-03-04 23:09:33
【问题描述】:

我正在将 zuul 网关迁移到 SCG。我的服务在 kubernetes 中运行并通过领事注册。 典型的服务名称是 xxx-service。因此,使用当前网关配置,我可以通过 http://address/api/xxx-service/some-path 调用它们

我当前的配置:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
          predicates:
            - name: Path
              args:
                pattern: "'/api/' + serviceId + '/**'"
          filters:
            - name: RewritePath
              args:
                regexp: "'/api/' + serviceId + '/(?<remaining>.*)'"
                replacement: "'/${remaining}'"

但客户应该在服务名称中不带“-service”后缀的情况下调用它们。如何配置 SCG 以便能够通过以下方式调用服务 http://address/api/xxx-service/some-path

之前的zuul配置:

zuul.routes.xxx.service-id=xxx-service
zuul.routes.aaa-bbb.service-id=aaa-bbb-service
zuul.routes.aaa-bbb.path=/aaa/bbb/**
zuul.strip-prefix=true
zuul.prefix=/api

【问题讨论】:

  • 你知道如何配置吗? @Silk0vsky
  • 嗨@Dolphin,抱歉回复晚了。我重新创建了我的解决方案作为答案。如果你有,请分享你的。

标签: java spring-cloud-gateway


【解决方案1】:

我处于完全相同的位置。你找到解决这个问题的诀窍了吗? 我知道我们可以像这样在 RouteLocator 中定义所有路线:

/**
 * Route constructions.
 *
 * @param builder
 *                the builder instance
 * @return the final route locator
 */
@Bean
public RouteLocator gatewayRoutes(final RouteLocatorBuilder builder) {
return builder.routes()
    // Declare First service
    .route(r -> r.path("/prefix/myservice1-service/**")
        .filters(f -> f.rewritePath("/prefix/myservicename1-service/(?<remaining>.*)", "/${remaining}"))
        .uri("lb://myservice1").id("myservice1"))

    // Declare Second service
    .route(r -> r.path("/prefix/myservice2-service/**")
        .filters(f -> f.rewritePath("/prefix/myservicename2-service/(?<remaining>.*)", "/${remaining}"))
        .uri("lb://myservice2").id("myservice2"))

    // Etc... Then build
    .build();
}

我不确定,但也许您需要禁用发现定位器才能正确执行此操作。

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false

但获得一个不那么肮脏的解决方案可能会很棒。

【讨论】:

    【解决方案2】:

    除了@Rémi Gélibert 变体,我们还可以实现我们自己的RouteLocator。它允许您为路由选择和特殊过滤器指定谓词,以便根据需要更改请求

    这样我们可以将路由配置提取到某种application.properties

    @Component
    public class CustomRouteLocator implements RouteLocator {
    
      Map<String, Pattern> prefixPatternsByServiceNames; // external configuration
      Map<String, String> prefixesByServiceNames;        // external configuration 
      Set<String> servicesNames;                         // external configuration
    
      @Override
      public Flux<Route> getRoutes() {
    
        return Flux.fromIterable(servicesNames)
            .map(serviceName -> Route.async()
                .id("ROUTE_" + serviceName)
                .predicate(exchange -> {
                  String path = exchange.getRequest().getPath().toString();
                  return prefixPatternsByServiceNames.get(serviceName).matcher(path).find();
                })
                .filter((exchange, chain) -> {
                  ServerHttpRequest origRequest = exchange.getRequest();
                  String query = origRequest.getURI().getQuery();
                  String originalPath = origRequest.getPath().toString();
                  String newPath = originalPath.substring(prefixesByServiceNames.get(serviceName).length());
    
                  ServerHttpRequest request = exchange.getRequest().mutate()
                      .path(query == null? newPath : newPath + "?" + query)
                      .build();
                  return chain.filter(exchange.mutate()
                      .request(request)
                      .build());
                })
                .uri("http://" + serviceName)
                .build());
      }
    
    }
    

    请注意:

    我的网关依赖于 kubernetes 服务发现,所以我改写 uri 这样uri("http://" + serviceName)

    如果您有 consul/eurica 发现集成,您可以尝试其他方式:uri("lb://" + serviceName)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-10
      • 2019-07-04
      • 1970-01-01
      • 2021-10-23
      • 2019-10-12
      • 1970-01-01
      • 2020-08-14
      • 2021-07-26
      相关资源
      最近更新 更多