Spring Cloud Gateway 教程

1、概览

本文将带你了解 Spring Cloud Gateway 的主要功能,它是一个基于 Spring Boot 和 Project Reactor 的网关。

Spring Cloud Gateway 提供开箱即用的路由机制,通常用于微服务应用中,把多个服务隐藏在 “Facade”(门面设计模式)后面。

2、路由处理器

Spring Cloud Gateway 专注于路由请求,它将请求转发给网关 Handler Mapping,由其决定如何处理与特定路由相匹配的请求。

从一个快速示例开始,看看 Gateway Handler 如何使用 RouteLocator 解析路由配置:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
      .route("r1", r -> r.host("**.baeldung.com")
        .and()
        .path("/baeldung")
        .uri("http://baeldung.com"))
      .route(r -> r.host("**.baeldung.com")
        .and()
        .path("/myOtherRouting")
        .filters(f -> f.prefixPath("/myPrefix"))
        .uri("http://othersite.com")
        .id("myOtherID"))
    .build();
}

注意,有几个核心的 API:

  • Route - 网关的主要 API。它由给定的标识(ID)、目的地(URI)和一组 PredicateFilter 定义
  • Predicate - Java 8 Predicate ,用于使用 Header、方法或参数匹配 HTTP 请求
  • Filter - 标准的 Spring WebFilter

3、动态路由

与 Zuul 一样,Spring Cloud Gateway 也提供了将请求路由到不同服务的方法。

路由配置可以通过纯 Java(如第 2 节中的示例所示,RouteLocator)或属性配置来创建:

spring:
  application:
    name: gateway-service  
  cloud:
    gateway:
      routes:
      - id: baeldung
        uri: baeldung.com
      - id: myOtherRouting
        uri: localhost:9999

4、路由工厂

Spring Cloud Gateway 使用 Spring WebFlux HandlerMapping 匹配路由。

它还包括许多内置的 Route Predicate 工厂。所有这些 Predicate 都与 HTTP 请求的不同属性相匹配。多个 Route Predicate 可通过逻辑 “and” 进行组合。

路由匹配既可以通过程序应用,也可以通过配置属性文件使用不同类型的 Route Predicate 工厂应用。

5、WebFilter 工厂

路由过滤器(Route Filter)可以修改传入的 HTTP 请求或传出的 HTTP 响应。

Spring Cloud Gateway 包含许多内置的 WebFilter 工厂,还可以创建自定义 Filter。

6、支持 Spring Cloud DiscoveryClient

Spring Cloud Gateway 可与 Eureka Server 和 Consul 等服务发现和注册中心轻松集成:

@Configuration
@EnableDiscoveryClient
public class GatewayDiscoveryConfiguration {
 
    @Bean
    public DiscoveryClientRouteDefinitionLocator 
      discoveryClientRouteLocator(DiscoveryClient discoveryClient) {
 
        return new DiscoveryClientRouteDefinitionLocator(discoveryClient);
    }
}

6.1、LoadBalancerClient Filter

LoadBalancerClientFilter 会使用 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 在 exchange attribute 中查找 URI。

如果 URL 采用 lb scheme(如 lb://baeldung-service),它将使用 Spring Cloud LoadBalancerClient 将名称(如 baeldung-service)解析为实际主机和端口。

未经修改的原始 URL 将被置于 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute 中。

7、监控

Spring Cloud Gateway 使用 Actuator API,这是一个著名的 Spring Boot 库,可为监控应用程序提供多种开箱即用的服务。

一旦安装并配置了 Actuator API,就可以通过访问 /gateway/ 端点来查看网关监控功能。

8、实践

现在,使用 path Predicate 创建一个将 Spring Cloud Gateway 用作代理服务器的简单示例。

8.1、依赖

dependencyManagement 中添加当前版本的 spring-cloud-dependencies 依赖:

<properties>
    <spring-cloud.version>2022.0.1</spring-cloud.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

接下来,添加必要的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

8.2、代码实现

application.yml 文件中创建一个简单的路由配置:

server:
  port: 80

spring:
  cloud:
    gateway:
      routes:
      - id: baeldung_route
        uri: http://baeldung.com
        predicates:
        - Path=/baeldung/
management:
  endpoints:
    web:
      exposure:
        include: "*"

Application 类:

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

应用启动后,可以访问网址 http://localhost/actuator/gateway/routes/baeldung_route,检查创建的路由配置:

{
    "id":"baeldung_route",
    "predicates":[{
        "name":"Path",
        "args":{"_genkey_0":"/baeldung"}
    }],
    "filters":[],
    "uri":"http://baeldung.com",
    "order":0
}

如你所见,相对网址 /baeldung 被配置为路由。因此,请求 http://localhost/baeldung/ 后,会被重定向到 http://baeldung.com,正如示例中配置的那样。

9、总结

本文介绍了 Spring Cloud Gateway 的部分功能和组件。


Ref:https://www.baeldung.com/spring-cloud-gateway