• 细说 Spring Cloud Gateway


    1. Spring Cloud Gateway 简介与核心概念

    微服务架构中,API 网关是一个非常重要的组件,它可以帮助我们实现服务的路由、负载均衡、认证授权等功能。Spring Cloud Gateway 是 Spring Cloud 官方推出的一个基于 Spring 5、Spring Boot 2 和 Project Reactor 的 API 网关实现。本文将介绍 Spring Cloud Gateway 的基本概念、核心组件以及如何配置和使用它。

    1.1. 什么是 Spring Cloud Gateway

    Spring Cloud Gateway 是一个基于 Spring Boot、Spring WebFlux 和 Project Reactor 的 API 网关实现,它提供了一种简单、高效的方式来构建微服务架构中的 API 网关。Spring Cloud Gateway 的主要功能包括:

    • 路由:根据请求的路径、方法等信息将请求转发到对应的微服务
    • 过滤:在请求被转发之前或之后对请求进行处理,如添加、修改请求头、响应头等
    • 断言:根据请求的信息判断是否满足某个条件,如请求路径是否匹配某个正则表达式
    • 负载均衡:在多个实例之间分配请求,以实现高可用和高性能

    1.2. Spring Cloud Gateway 与其他 API 网关的比较

    市面上有很多 API 网关的实现,如 Nginx、Zuul、Kong 等。与这些 API 网关相比,Spring Cloud Gateway 有以下优势:

    • 基于 Spring Boot 和 Spring Cloud,与 Spring 生态系统集成更加紧密
    • 使用非阻塞式 I/O 和响应式编程模型,性能更高
    • 提供了丰富的过滤器和断言,可以方便地实现各种功能
    • 支持动态路由和动态配置,更加灵活

    1.3. Spring Cloud Gateway 的核心组件

    Spring Cloud Gateway 的核心组件主要包括以下几个:

    • Route(路由):路由是网关的基本构建块,它定义了请求如何被转发到微服务。一个路由包含一个 ID、一个断言和一个过滤器链。
    • Predicate(断言):断言用于判断请求是否满足某个条件,如请求路径是否匹配某个正则表达式。断言可以用于选择性地应用过滤器或路由请求。
    • Filter(过滤器):过滤器用于在请求被转发之前或之后对请求进行处理,如添加、修改请求头、响应头等。过滤器分为局部过滤器和全局过滤器,局部过滤器只作用于特定的路由,而全局过滤器作用于所有路由。
    • LoadBalancer(负载均衡器):负载均衡器用于在多个实例之间分配请求,以实现高可用和高性能。Spring Cloud Gateway 集成了 Spring Cloud LoadBalancer,可以方便地实现负载均衡。

    2. Spring Cloud Gateway 的配置与使用

    接下来,我们将介绍如何搭建和配置 Spring Cloud Gateway,以及如何使用断言、过滤器和路由等功能。

    2.1. 如何搭建和配置 Spring Cloud Gateway

    要搭建一个 Spring Cloud Gateway 项目,首先需要创建一个 Spring Boot 项目,并添加以下依赖:

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-gatewayartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    然后,在 application.ymlapplication.properties 文件中配置 Spring Cloud Gateway,如下所示:

    spring:
      cloud:
        gateway:
          routes:
          - id: user-service
            uri: lb://user-service
            predicates:
            - Path=/user/**
            filters:
            - StripPrefix=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上面的配置定义了一个名为 user-service 的路由,当请求路径以 /user 开头时,请求将被转发到 user-service 微服务。StripPrefix=1 表示在转发请求之前去掉路径中的第一个部分(即 /user)。

    2.2. 断言的使用

    2.2.1. 内置断言

    Spring Cloud Gateway 提供了一些内置的断言,如 PathMethodHeader 等。下面是一些常用的内置断言的示例:

    • Path=/user/**:匹配路径以 /user 开头的请求
    • Method=GET:匹配 GET 请求
    • Header=X-Requested-With, XMLHttpRequest:匹配包含 X-Requested-With 头且值为 XMLHttpRequest 的请求

    2.2.2. 自定义断言

    除了内置的断言,我们还可以自定义断言。要创建一个自定义断言,需要实现 GatewayPredicate 接口,并将其注册为 Spring Bean。下面是一个简单的自定义断言示例:

    @Component
    public class CustomPredicate implements GatewayPredicate {
    
        @Override
        public boolean test(ServerWebExchange exchange) {
            // 自定义断言逻辑
            return true;
        }
    
        @Override
        public GatewayPredicate negate() {
            return new CustomPredicate();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.3. 过滤器的使用

    2.3.1. 局部过滤器

    局部过滤器是只作用于特定路由的过滤器。要创建一个局部过滤器,需要实现 GatewayFilter 接口,并将其注册为 Spring Bean。下面是一个简单的局部过滤器示例:

    @Component
    public class CustomFilter implements GatewayFilter {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 在请求被转发之前的处理逻辑
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // 在请求被转发之后的处理逻辑
            }));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3.2. 全局过滤器

    全局过滤器是作用于所有路由的过滤器。要创建一个全局过滤器,需要实现 GlobalFilter 接口,并将其注册为 Spring Bean。下面是一个简单的全局过滤器示例:

    @Component
    public class CustomGlobalFilter implements GlobalFilter {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 在请求被转发之前的处理逻辑
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // 在请求被转发之后的处理逻辑
            }));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3.3. 自定义过滤器

    除了内置的过滤器,我们还可以自定义过滤器。要创建一个自定义过滤器,需要实现 GatewayFilterFactory 接口,并将其注册为 Spring Bean。下面是一个简单的自定义过滤器示例:

    @Component
    public class CustomFilterFactory implements GatewayFilterFactory<CustomFilterFactory.Config> {
    
        @Override
        public GatewayFilter apply(Config config) {
            return new CustomFilter(config);
        }
    
        @Override
        public Class<Config> getConfigClass() {
            return Config.class;
        }
    
        public static class Config {
            // 自定义过滤器配置
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.4. 路由的使用

    2.4.1. 基于集群负载均衡路由

    Spring Cloud Gateway 集成了 Spring Cloud LoadBalancer,可以方便地实现负载均衡。要使用负载均衡,只需将路由的 URI 设置为 lb://,如下所示:

    spring:
      cloud:
        gateway:
          routes:
          - id: user-service
            uri: lb://user-service
            predicates:
            - Path=/user/**
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.4.2. 动态路由的实现

    Spring Cloud Gateway 支持动态路由,可以在运行时修改路由配置。要实现动态路由,需要实现 RouteDefinitionLocator 接口,并将其注册为 Spring Bean。下面是一个简单的动态路由示例:

    @Component
    public class CustomRouteDefinitionLocator implements RouteDefinitionLocator {
    
        @Override
        public Flux<RouteDefinition> getRouteDefinitions() {
            // 从数据库、配置中心等地方获取路由配置
            List<RouteDefinition> routeDefinitions = new ArrayList<>();
            return Flux.fromIterable(routeDefinitions);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.4.3. 检索网关中定义的路由

    要检索网关中定义的路由,可以使用 RouteLocator 接口。下面是一个简单的示例:

    @Autowired
    private RouteLocator routeLocator;
    
    public void printRoutes() {
        routeLocator.getRoutes().subscribe(route -> {
            System.out.println("Route ID: " + route.getId());
            System.out.println("Route URI: " + route.getUri());
        });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    总结

    通过上面的介绍,相信大家已经对 Spring Cloud Gateway 有了一定的了解。在实际项目中,我们可以根据需求灵活地使用断言、过滤器和路由等功能,构建出功能强大、性能优越的 API 网关。

  • 相关阅读:
    C++进阶:二叉搜索树介绍、模拟实现(递归迭代两版本)及其应用
    FTC局部路径规划代码分析
    Python Lambda 常用使用方法汇总(结合fliter\map\reduce等函数)
    WPF+ASP.NET SignalR实现后台通知
    C++初阶(三)
    VMware设置共享文件夹
    估算总体标准差的极差均值估计法sigma = R/d2
    积分球测量作用
    springboot和vue:四、web入门(静态资源访问+文件上传+拦截器)
    Docker-07:Docker网络管理
  • 原文地址:https://blog.csdn.net/heihaozi/article/details/131452119