【Spring知识】Spring cloud gateway使用详解

概述

Spring Cloud Gateway 是Spring Cloud生态系统中的一个项目,它是基于Spring Framework 5、Reactor和Spring Boot 2.0构建的。它旨在为微服务架构提供一种简单而有效的API路由管理方式,并且基于Filter的方式提供网关的基本功能,如安全认证、监控、限流等。以下是Spring Cloud Gateway的一些详细介绍:

  1. 响应式编程模型
    Spring Cloud Gateway是基于Spring WebFlux框架开发的,它支持响应式编程模型。这意味着它可以以非阻塞的方式处理请求,从而提高系统的吞吐量和可伸缩性 。

  2. 动态路由
    Spring Cloud Gateway支持动态路由,能够匹配任何请求属性上的路由。这使得开发者可以根据需要灵活地调整路由规则,而不需要重启服务 。

  3. 集成Hystrix
    Spring Cloud Gateway集成了Hystrix断路器,这使得它可以在下游服务不可用时提供回退逻辑,以防止系统过载 。

  4. 过滤器和断言
    Spring Cloud Gateway提供了多种内置的过滤器(如AddRequestHeaderSetResponseHeaderSetStatus等),这些过滤器可以在请求被路由之前或之后执行,以修改请求和响应。此外,它还提供了多种断言工厂,如PathMethodHeader等,用于匹配路由 。

  5. 支持Spring Cloud DiscoveryClient
    Spring Cloud Gateway支持与Spring Cloud DiscoveryClient集成,这意味着它可以与服务发现和注册机制配合使用,动态地注册和发现服务 。

  6. 限流
    Spring Cloud Gateway支持限流功能,可以限制对特定路由的访问频率。这通常通过令牌桶算法实现,以控制请求的速率 。

  7. TLS和SSL支持
    Spring Cloud Gateway支持TLS和SSL,这意味着它可以处理HTTPS请求,并提供安全的通信通道 。

  8. 配置
    Spring Cloud Gateway的配置可以通过Java DSL或在application.yml中进行。配置包括路由规则、过滤器和限流策略等 。

  9. 监控
    Spring Cloud Gateway提供了实时监控的功能,可以通过/actuator/gateway/routes端点来查看路由的状态和指标 。

Spring Cloud Gateway的设计目标是提供一种声明式的、基于WebFlux的API网关,它旨在为微服务架构提供动态的、高效的路由能力。通过使用Spring Cloud Gateway,开发者可以轻松地构建一个强大而灵活的API网关,以支持复杂的路由需求和高并发的流量。

🛠️ 如何自定义Spring Cloud Gateway的过滤器?

在Spring Cloud Gateway中自定义过滤器(GatewayFilter)是一种非常强大的机制,它允许开发者根据特定的业务需求来修改传入的HTTP请求或传出的HTTP响应。以下是如何自定义Spring Cloud Gateway的过滤器的详细说明:

1. 实现GatewayFilter接口

要创建一个自定义过滤器,首先需要实现GatewayFilter接口,并重写其filter方法。这个方法会在请求被路由之前或之后执行,允许你修改请求和响应。

@Component
public class CustomGatewayFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 在这里添加你的前置逻辑,比如修改请求头、参数等
        ServerHttpRequest request = exchange.getRequest();
        // 示例:添加一个请求头
        request.mutate().header("Custom-Header", "Value").build();
        
        // 继续过滤器链
        return chain.filter(exchange)
            .then(Mono.fromRunnable(() -> {
                // 在这里添加你的后置逻辑,比如修改响应头等
                ServerHttpResponse response = exchange.getResponse();
                // 示例:添加一个响应头
                response.getHeaders().add("Custom-Response-Header", "Value");
            }));
    }

    @Override
    public int getOrder() {
        // 返回过滤器的顺序值,值越小,优先级越高
        return -1;
    }
}

在上述代码中,filter方法首先修改了传入请求的请求头,然后继续执行过滤器链。在过滤器链执行完毕后,再修改响应头。getOrder方法用于指定过滤器的执行顺序,值越小,优先级越高 。

2. 注册过滤器到路由

自定义的过滤器可以通过Java配置或在application.yml中进行配置,然后应用到特定的路由上。

Java配置方式:
@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("custom_route", r -> r.path("/custom-path/**")
                .filters(f -> f.filter(new CustomGatewayFilter()))
                .uri("http://localhost:8080"))
            .build();
    }
}

在上述配置中,自定义过滤器CustomGatewayFilter被应用到了路径为/custom-path/**的路由上 。

YAML配置方式:
spring:
  cloud:
    gateway:
      routes:
      - id: custom_route
        uri: http://localhost:8080
        predicates:
          - Path=/custom-path/**
        filters:
          - name: CustomGatewayFilter
            args:
              order: 1

在上述YAML配置中,CustomGatewayFilter过滤器被应用到了路径为/custom-path/**的路由上,并且指定了过滤器的顺序值为1 。

3. 使用AbstractGatewayFilterFactory创建过滤器工厂

如果你需要更灵活的过滤器配置,可以通过继承AbstractGatewayFilterFactory来创建一个过滤器工厂。这种方式允许你定义配置选项,并且可以通过工厂模式来创建多个不同的过滤器实例。

@Component
public class CustomFilterFactory extends AbstractGatewayFilterFactory<CustomFilterFactory.Config> {
    public CustomFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // 实现过滤器逻辑
            return chain.filter(exchange);
        };
    }

    public static class Config {
        // 定义配置参数
    }
}

在上述代码中,CustomFilterFactory是一个自定义的过滤器工厂,它允许你在路由配置中指定过滤器的配置参数 。

4. 配置路由使用过滤器工厂

spring:
  cloud:
    gateway:
      routes:
      - id: custom_route_with_factory
        uri: http://localhost:8080
        predicates:
          - Path=/custom-path-factory/**
        filters:
          - name: CustomFilterFactory
            args:
              myArg: "value"

在上述YAML配置中,通过CustomFilterFactory过滤器工厂应用了一个自定义过滤器到路径为/custom-path-factory/**的路由上 。

通过上述步骤,你可以在Spring Cloud Gateway中实现各种自定义的过滤器,以满足特定的业务需求。自定义过滤器可以用于实现请求日志记录、身份验证、请求头修改、响应头修改等多种功能。

路由配置

在Spring Cloud Gateway中,路由配置是核心功能之一,它定义了如何将 incoming HTTP 请求路由到指定的服务或URL。以下是Spring Cloud Gateway路由配置的详细介绍和示例:

基本路由配置

Spring Cloud Gateway支持通过Java配置和YAML配置两种方式来定义路由。

Java配置方式

在Java配置中,你可以使用RouteLocator Bean来定义路由:

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("path_route", r -> r.path("/api/**")
                        .uri("http://localhost:8080"))
                .route("host_route", r -> r.host("*.example.com")
                        .uri("http://localhost:8080"))
                .route("method_route", r -> r.method(HttpMethod.GET)
                        .uri("http://localhost:8080"))
                .build();
    }
}

在上面的配置中,定义了三个路由:

  • path_route:匹配路径以/api/开头的请求,并将其转发到http://localhost:8080
  • host_route:匹配任何以.example.com结尾的请求主机头,并将其转发到http://localhost:8080
  • method_route:仅当请求方法是GET时,将请求转发到http://localhost:8080
YAML配置方式

application.ymlapplication.yaml文件中,你可以如下定义路由:

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: http://localhost:8080
        predicates:
        - Path=/api/**
      - id: host_route
        uri: http://localhost:8080
        predicates:
        - Host=**.example.com
      - id: method_route
        uri: http://localhost:8080
        predicates:
        - Method=GET

路由谓词

Spring Cloud Gateway提供了多种内置的路由谓词工厂,用于定义路由匹配的条件,如:

  • Path:路径匹配。
  • Host:主机头匹配。
  • Method:HTTP方法匹配。
  • Header:请求头匹配。
  • Query:查询参数匹配。
  • After:时间匹配。
  • Before:时间匹配。

路由过滤器

除了路由谓词,Spring Cloud Gateway还允许你在路由上应用过滤器。过滤器可以在请求被路由之前或之后执行,用于修改请求或响应。例如,添加请求头、修改路径、设置响应头等。

@Bean
public GatewayFilterChain gatewayFilterChain() {
    return new DefaultGatewayFilterChain();
}

在Java配置中,你可以如下定义过滤器:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
                .route("path_route", r -> r.path("/api/**")
                        .filters(f -> f.addRequestHeader("X-Request-Red", "Blue"))
                        .uri("http://localhost:8080"))
                .build();
}

在上面的配置中,addRequestHeader过滤器会在请求被路由之前添加一个请求头X-Request-Red

动态路由配置

Spring Cloud Gateway支持动态路由配置,这意味着你可以在运行时动态地添加、修改或删除路由,而不需要重启服务。这通常通过集成配置中心或数据库来实现。

集成Spring Cloud Config

Spring Cloud Config是一个配置管理工具,它可以集中管理配置信息,并支持动态刷新配置。通过集成Spring Cloud Config,Spring Cloud Gateway可以动态地加载和刷新路由配置。

集成数据库

你也可以将路由配置存储在数据库中,并使用Spring Cloud Gateway提供的RouteLocator Bean来动态加载和更新路由。

通过上述路由配置方法,Spring Cloud Gateway提供了灵活、可扩展的路由管理能力,以支持复杂的路由需求和高并发的流量。

实现动态路由

在Spring Cloud Gateway中,动态路由是指在运行时根据条件动态地添加、修改或删除路由,而不需要重新启动服务。这通常通过与一个动态的路由源(如数据库、配置中心等)集成来实现。以下是实现动态路由的一些步骤和考虑因素:

1. 集成动态路由源

首先,你需要选择一个动态的路由源来存储路由配置。常见的选择包括:

  • 数据库:如MySQL、PostgreSQL等。
  • 配置中心:如Spring Cloud Config Server、Consul、Etcd或Zookeeper。

2. 创建路由实体

定义一个实体类来表示路由配置,这个实体类应该包含所有必要的路由信息,如ID、URI、谓词、过滤器等。

public class DynamicRoute {
    private String id;
    private String uri;
    private List<String> predicates;
    private List<String> filters;
    // getters and setters
}

3. 动态加载路由配置

创建一个服务来从路由源动态加载路由配置,并将其转换为Route对象。

@Service
public class DynamicRouteService {
    private final RouteLocator routeLocator;
    private final DynamicRouteRepository dynamicRouteRepository;

    public DynamicRouteService(RouteLocator routeLocator, DynamicRouteRepository dynamicRouteRepository) {
        this.routeLocator = routeLocator;
        this.dynamicRouteRepository = dynamicRouteRepository;
    }

    public void loadDynamicRoutes() {
        List<DynamicRoute> routes = dynamicRouteRepository.findAll();
        routes.forEach(this::updateRoute);
    }

    private void updateRoute(DynamicRoute dynamicRoute) {
        Route route = RouteLocator.parse(dynamicRoute.getId(),
                dynamicRoute.getUri(),
                Arrays.asList(dynamicRoute.getPredicates()),
                Arrays.asList(dynamicRoute.getFilters()));
        routeLocator.updateRouteId(route.getId(), route);
    }
}

4. 监听路由源变化

使用事件监听或轮询机制来监听路由源的变化,并动态更新路由。

事件监听方式:

如果使用Spring Cloud Config Server,可以监听配置变化事件。

轮询方式:

定期查询数据库或配置中心,检查路由配置是否有变化,并更新路由。

@Scheduled(fixedDelay = 10_000) // 每10秒检查一次
public void refreshRoutes() {
    DynamicRouteService dynamicRouteService = applicationContext.getBean(DynamicRouteService.class);
    dynamicRouteService.loadDynamicRoutes();
}

5. 实现/refresh端点

Spring Cloud Gateway提供了一个/refresh端点,可以通过发送HTTP POST请求来触发路由刷新。

management:
  endpoints:
    web:
      exposure:
        include: refresh

6. 考虑事务和一致性

在动态更新路由时,需要确保路由配置的一致性和事务性,特别是在高并发场景下。

7. 监控和日志

实施实时监控和日志记录,以便及时发现和解决路由配置的问题。

通过上述步骤,你可以在Spring Cloud Gateway中实现动态路由,使得路由配置可以在运行时动态更新,而不需要重启服务。这为微服务架构提供了更高的灵活性和可扩展性。

从零开始配置部署一个网关

要从头开始部署一个Spring Cloud Gateway网关服务,你需要完成以下步骤:

1. 设置开发环境

确保你的开发环境中安装了以下软件:

  • Java Development Kit (JDK) 1.8 或更高版本。
  • Maven 或 Gradle 作为构建工具。
  • IntelliJ IDEA、Eclipse 或其他Java IDE。
  • Git 客户端(如果从GitHub等平台克隆项目)。
  • 可选:Docker,用于容器化部署。

2. 创建Spring Boot项目

使用Spring Initializr(https://start.spring.io/)来生成一个新的Spring Boot项目,或者手动创建一个Maven或Gradle项目,并添加必要的依赖。

使用Spring Initializr生成项目:
  • 选择项目元数据(Group, Artifact, Name, Description)。
  • 添加依赖:Spring Web, Spring Cloud Gateway, Eureka Discovery Client(如果你使用服务发现)。
  • 生成项目并下载压缩包。
  • 解压下载的压缩包到你喜欢的IDE中。
Maven依赖示例:
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!-- 如果使用服务发现 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>你的Spring Cloud版本</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
Gradle依赖示例:
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    // 如果使用服务发现
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    dependencies {
        dependencySet('org.springframework.cloud:spring-cloud-dependencies:你的Spring Cloud版本') {
            with {
                version { require GroupArtifact.version }
                withJavadoc()
                withSources()
            }
        }
    }
    repositories {
        mavenCentral()
        jcenter()
    }
}

3. 配置Spring Cloud Gateway

src/main/resources/application.ymlapplication.properties文件中配置网关路由。

application.yml示例:
server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
      - id: myservice_route
        uri: http://localhost:8081
        predicates:
        - Path=/myservice/**
        filters:
        - StripPrefix=1
    application:
      name: gateway-service

eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    preferIpAddress: true

4. 实现路由逻辑

创建一个配置类来定义路由。

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("my-service", r -> r.path("/myservice/**")
                        .uri("http://localhost:8081"))
                .build();
    }
}

5. 启动网关服务

运行Application.java或对应的主类来启动Spring Boot应用。

@SpringBootApplication
public class GatewayServiceApplication {

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

6. 测试网关服务

使用浏览器或工具(如curl或Postman)测试网关路由是否按预期工作。

curl http://localhost:8080/myservice/somePath

确保请求被正确地路由到目标服务。

7. 部署到生产环境

在将网关服务部署到生产环境之前,进行彻底的测试,并确保所有配置都符合生产环境的要求。可以使用Docker容器、Kubernetes或其他云服务来部署和管理网关服务。

以上步骤提供了一个基本的指南来从零开始部署一个Spring Cloud Gateway网关服务。根据具体需求,可能需要进行额外的配置和优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问道飞鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值