Spring Gateway基础知识总结

本文主要总结Spring Gateway的基础用法,内容包括网关、Spring Gateway工作流程、Spring Cloud Gateway搭建、路由配置方式、负载均衡实现、断言工厂这几个部分

目录

1. 网关

1.1 网关介绍

1.2 网关对比

1.3 Spring Gateway

1.4 核心概念

1.6 总结

2. Spring Gateway工作流程

2.1 官网上的核心工作流程

核心流程:

核心点:

2.2 Spring Gateway执行流程

总结

3. Spring Cloud Gateway搭建

3.1 Gateway搭建

3.2 总结

4. Gateway路由配置方式

4.1 Gateway Config

4.2 通过yml文件配置

5. Gateway实现负载均衡

5.1 什么是负载均衡

5.2 自动负载均衡

5.3 手动负载均衡

6. Gateway断言Predicate

6.1 断言种类

7. Gateway的Filter

7.1 内置Filter

7.1.1 内置过滤器分类

7.1.2 内置过滤器配置

7.2 自定义Filter


1. 网关

1.1 网关介绍

在微服务架构中,一个系统会被拆分为多个微服务,那么作为客户端如何去调用这些微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用,这样会产生很多问题:

  • 客户端多次请求不同的微服务,增加了客户端代码或配置编写的复杂性
  • 认证复,每个微服务需要独立认真
  • 存在跨域问题,在一定场景下处理相对复杂

为了解决上述问题引入了网关概念:所谓的API网关就是指系统的统一入口,提供内部服务的路由中转,为客户端提供统一的服务,一些与业务本身功能无关的公共逻辑可以在这里实现,例如认证、鉴权、监控、路由转发等。

1.2 网关对比

Zuul、Nginx+Lua 和 Spring Cloud Gateway 都可以用作API网关,但它们在不同方面有一些不同之处,包括性能、扩展性、功能和用途。以下是它们的主要比较:

  1. Zuul: 2. 性能:Zuul性能较低,特别是在处理大量并发请求时。它使用的是阻塞I/O,每个请求都会占用一个线程。 3. 扩展性:Zuul的扩展性相对较低。定制功能需要使用过滤器,这可能不够灵活。 4. 功能:Zuul是Netflix OSS的一部分,提供基本的路由、负载均衡、重试等功能。然而,它的功能相对有限。 5. 用途:适合小规模的、非高并发的应用,或者作为微服务架构中的较早版本API网关。

  2. Nginx+Lua: 2. 性能:Nginx以其出色的性能而闻名。Nginx+Lua的组合可以在处理高并发请求时提供高性能,特别适合于需要低延迟的应用。 3. 扩展性:Nginx+Lua提供了强大的扩展性。使用Lua脚本,你可以定制和扩展其功能以适应各种需求。 4. 功能:Nginx是一个功能强大的反向代理服务器,可以处理负载均衡、缓存、SSL终端、请求重写、安全性等各种功能。 5. 用途:适合高并发的生产环境,特别是需要高性能和低延迟的应用,一般用于一层网关。

  3. Spring Cloud Gateway: 2. 性能:Spring Cloud Gateway在性能方面表现不错,它使用基于反应性的编程模型,充分利用非阻塞I/O。 3. 扩展性:Spring Cloud Gateway提供了很好的扩展性,它是基于Spring Framework构建的,因此可以与Spring生态系统的其他组件无缝集成。 4. 功能:Spring Cloud Gateway提供了路由、过滤器、限流、熔断等功能,可以满足大多数API网关的需求。 5. 用途:适合构建微服务架构中的API网关,特别是在使用Spring Boot和Spring Cloud的应用中。

1.3 Spring Gateway

Spring Cloud Gateway是一个用于构建API网关的开源项目,它是Spring Cloud生态系统的一部分。API网关是微服务架构中的关键组件之一,用于管理和路由传入的请求,提供了一种集中化的访问点,可以实现诸如路由、负载均衡、身份验证、安全性、监控、限流、重试等功能。Spring Cloud Gateway提供了一种现代、动态、灵活且功能强大的方式来处理这些任务。

以下是Spring Cloud Gateway的一些主要特点和功能:

  1. 动态路由:Spring Cloud Gateway允许你根据需要动态配置路由,这意味着你可以在不停止网关的情况下修改路由规则。路由配置通常存储在配置中心(如Spring Cloud Config)中,从而实现灵活的路由管理。

  2. 过滤器:Gateway提供了一组预定义的过滤器,用于请求和响应的修改、校验、验证和监控。你还可以编写自定义过滤器以适应特定需求。

  3. 负载均衡:Gateway集成了Spring Cloud LoadBalancer,可实现请求的负载均衡。你可以将请求路由到多个后端服务实例,实现高可用和扩展性。

  4. 限流和熔断:Spring Cloud Gateway支持通过集成Hystrix来实现限流和熔断功能,以保护后端服务免受过多的请求压力。

  5. 安全性:可以与Spring Security或其他身份验证和授权机制集成,实现安全的API访问。

  6. 监控和指标:Spring Cloud Gateway集成了Spring Boot Actuator,提供了各种有用的监控和度量信息,可以使用Micrometer将这些信息导出到多个监控系统。

  7. WebSockets支持:Gateway支持WebSockets,因此可以处理实时通信的需求。

  8. HTTP/2支持:可以通过配置启用HTTP/2协议,以提高性能。

  9. 自定义路由规则:除了使用配置外,你还可以编写自定义的路由规则,以实现更复杂的路由需求。

Spring Cloud Gateway是建立在Spring Framework和Spring Boot的基础上的,因此与Spring生态系统的其他组件无缝集成。它为构建微服务架构中的API网关提供了灵活、高性能和现代的解决方案。

  • 特点:
    • 性能强大:是Zuul性能的1.6倍
    • 功能强大:内置了很多实用功能,如转发、监控、限流等
    • 设计优雅,易于拓展

1.4 核心概念

在Spring Gateway中:

  • 路由(Route):路由是网关的基本构建单元,包括以下属性:

    • ID(标识):路由的唯一标识。
    • URI(目标URI):定义路由请求将被转发到的目标URI。
    • 断言(Predicates):一组谓词,用于匹配HTTP请求的属性,如路径、主机、标头等。
    • 过滤器(Filters):一组过滤器,用于在请求到达目标URI之前或响应返回之前对请求和响应进行修改。

    举例:定义一个路由,将匹配/example路径的请求,将其转发到http://example.com

  • id: example_route uri: example.com predicates:
    • Path=/example
  • 断言(Predicate):谓词是用于匹配HTTP请求的条件。谓词可以基于请求的各种属性,如路径、主机、标头等。例如,Path谓词可以匹配请求路径。

    举例:定义一个谓词,要求请求路径必须以/api开头:

predicates:

  • Path=/api/**
  • 过滤器(Filter):过滤器是网关中的处理器,它们可以在请求到达目标URI之前或响应返回之前对请求和响应进行修改。过滤器可以用于添加标头、修改请求体、记录日志等操作。

    举例:定义一个过滤器,向响应标头中添加X-Custom-Header标头:

filters:

  • AddResponseHeader=X-Custom-Header, Gateway

这些组件一起构成了Spring Gateway的核心功能,允许您定义路由规则、请求匹配条件以及请求和响应的处理操作。

1.6 总结

SpringCloud Gateway使用的是WebFlux中的reactor-netty响应式编程组件,底层使用Netty通讯框架。

2. Spring Gateway工作流程

2.1 官网上的核心工作流程

核心流程图如下:

核心流程:
  • 客户端(Gateway Client)向 Spring Cloud Gateway发送请求。
  • 如果Gateway Handler Mapping确定请求与路由匹配,则将其发送到Gateway Web Handler处理程序。
  • 接着处理程序通过特定于请求的Filter链过滤请求。Filter被虚线分隔的原因是Filter可以在发送代理请求之前(pre)和之后(post)运行逻辑。执行所有pre过滤器逻辑,然后进行代理请求,发送代理请求之后,运行“post”过滤器逻辑
    • 过滤器作用:
      • Filter在pre类型的过滤器可以做参数校验,权限校验、流量监控、日志输出和协议转换等。
      • Filter在Post类型的过滤器可以做响应内容、响应头的修改、日志输出和流量监控等
核心点:
  • Route(路由):路由是构建网关的基础模块儿,它由ID,目标URI,包括一系列的断言喝过滤器组成,如果断言为True则匹配该路由。
  • Predicate(断言):开发人员可以匹配http请求中的所有内容(如:请求头或请求参数),请求与断言匹配则进行路由。
  • Filter(过滤):指Spring框架中GatewayWayFilter的实例,使用过滤器可以在请求被路由前或者之后对请求进行修改。
  • 三个核心点连起来:当用户的请求到达Gateway,Gateway会通过一些匹配条件,定位到真正的服务节点,并在这个转发过程前后,进行一些细化控制。其中Predicate就是我们的匹配条件,Filter可以理解为一个过滤器,有了这两点,再加上目标URI就可以实现一个具体路由了

2.2 Spring Gateway执行流程

如上图所示,当使用Spring Gateway处理请求时,它经历以下流程:

  1. Client向Gateway Server发送请求: 客户端(例如浏览器、移动应用或其他服务)发送HTTP请求到Spring Gateway服务器,这是请求的起始点。

  2. 请求会被HttpWebHandlerAdapter提取组装成网关上下文:

    请求进入Spring Gateway后,首先被HttpWebHandlerAdapter处理。这个组件负责提取HTTP请求信息,并将其组装成网关上下文对象,其中包括请求的各种信息,如HTTP头、请求参数等。

  3. 网关上下文会传递到DispatcherHandler:

    组装好的网关上下文被传递到DispatcherHandler,它是Spring Gateway的核心处理器。DispatcherHandler的任务是将请求分发到合适的处理程序。

  4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用:

    RoutePredicateHandlerMapping负责路由查找,它将根据网关上下文中的信息选择适当的路由。每个路由都包括一个或多个路由断言,这些断言是用来判断该路由是否适用于当前请求的条件。

  5. 如果断言成功,由FilteringWebHandler创建过滤器链并调用:

如果路由断言成功,表示当前请求匹配了某个路由规则。此时,将会由FilteringWebHandler创建一个过滤器链,并按照链的顺序调用这些过滤器。过滤器可以在请求到达后端服务之前或响应返回给客户端之前对请求进行修改、验证或记录日志等操作。

这个流程允许Spring Gateway进行请求的路由和过滤,以实现对请求的控制和处理。通过配置不同的路由规则和过滤器,可以根据请求的性质来决定如何处理请求,例如路由到不同的后端服务、添加安全性措施或改变请求和响应的内容。

总结

Gateway的核心流程就是:路由转发+执行过滤器链

3. Spring Cloud Gateway搭建

3.1 Gateway搭建

搭建一个cloud-alibaba-gateway项目,因为使用了spring cloud 所以需要注意版本间的匹配,这里可以通过阿里的云原生脚手架去获取适合的版本:[start.aliyun.com/]

搭建Spring Gateway项目之前需要一些前置搭建微服务注册中心(Nacos,Consul,Eureka等),这里我使用Nacos进行演示,Nacos的搭建流程可以参考:[juejin.cn/post/705471…]

该案例的完整代码可以在gitee项目中获取:[gitee.com/lei-qinghua…]

  • pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ts</groupId>
    <artifactId>cloud-alibaba-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloud-alibaba-gateway</name>
  
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
        <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
        <spring-cloud.version>2021.0.5</spring-cloud.version>
    </properties>
  
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <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>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.ts.demo.DemoApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

注意:引入Gateway一定要删除spring-boot-starter-web依赖,否则会发生冲突无法引入。

  • yml
server:
  port: 9999
  
spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true  # 开启了spring gateway
      routes:
        - id: nacos-provider #服务id,对应nacos中注册的服务名
          uri: http://localhost:9003/nacos-provider #访问的uri地址
          predicates:
            - Path=/ts/** #断言,对请求进行匹配,只有包含/ts的路径才能通过断言

  • controller (微服务cloud-alibaba-provider-9003)

    这里我们搭建了另外一个微服务cloud-alibaba-provider-9003作为服务的提供者来验证网关是否生效,这个微服务的逻辑非常简单,使用HashMap模拟一个一个数据库的获取操作如下:

@RequestMapping("/ts")
@RestController
public class DataController {
    @Value("${server.port}")
    String serverPort;
  
    public static HashMap<Long,String> hashMap = new HashMap<>();
    static {
        hashMap.put(1l,"鼠标");
        hashMap.put(2l,"键盘");
        hashMap.put(3l,"耳机");
    }
  
    @GetMapping("info/{id}")
    public JsonResult<String> msbSQL(@PathVariable("id") Long id) {
        JsonResult<String> result = new JsonResult<>(200,"ServerPort: "+serverPort+":"+hashMap.get(id));
        return result;
    }
  
    @GetMapping("/timeout")
    public JsonResult<String> timeout(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return new JsonResult<>(200,"ServerPort: "+serverPort);
    }
}
  • 测试:[http://localhost:9999/ts/timeout]

    如下图所示,我们通过微服务提供者的url对服务进行访问,而是通过gateway网关的路径对微服务进行访问成功了,就说明我们的网关搭建成功了。

3.2 总结

这里以一个简单的例子展示了Spring Gateway网关的基础搭建和测试过程,相关的服务搭建都是在本地完成的,完整的代码请参考我的gitee项目:[gitee.com/lei-qinghua…]

4. Gateway路由配置方式

在第三节中我们用yml文件对Gateway的路由方式进行了配置,实际上Gateway还可以通过Java代码的方式来进行路由配置。

4.1 Gateway Config

通过@Bean 注入一个RouteLocator,代码如下:

package com.example.cloudalibabagateway.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes =routeLocatorBuilder.routes();
        routes.route("path_ts",r -> r.path("/ts/**").uri("http://localhost:9003/nacos-provider"));
        return routes.build();
    }
}

4.2 通过yml文件配置

server:
  port: 9999

spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: nacos-provider
          uri: http://localhost:9003/nacos-provider
          predicates:
            - Path=/ts/**

5. Gateway实现负载均衡

5.1 什么是负载均衡

微服务系统的负载均衡是一种机制,用于在微服务架构中均匀分配网络请求和流量到不同的微服务实例,以确保各个服务的资源充分利用,提高系统的性能、可用性和稳定性。在微服务架构中,通常存在多个相同或相似的微服务实例,每个实例都提供相同的服务接口,但可能运行在不同的主机或容器上。

以下是微服务系统中负载均衡的一些关键概念和特点:

  1. 服务实例均衡分配:微服务负载均衡确保来自客户端的请求均匀分布到不同的服务实例上,以防止某些实例过载而其他实例处于空闲状态。

  2. 多种负载均衡策略:微服务负载均衡可以采用不同的策略,如轮询、随机、最少连接等,以选择目标服务实例。每种策略有其用途,根据具体情况选择合适的策略。

  3. 健康检查:负载均衡器定期检查每个服务实例的健康状态,以确定哪些实例可以接收请求。如果某个实例不健康或不可用,负载均衡器将停止将请求路由到该实例。

  4. 自动扩展:微服务系统的负载均衡应该支持自动扩展。当系统负载增加时,可以自动添加新的服务实例以处理更多请求。这有助于应对流量波动和系统的横向扩展。

  5. 故障转移:如果某个服务实例出现故障,负载均衡器应该自动将流量转移到其他健康的实例,以确保系统的可用性。

  6. 会话粘附:在某些情况下,需要确保同一客户端的多个请求被路由到同一服务实例,以维护会话一致性。这称为会话粘附,一些负载均衡器支持此功能。

微服务系统的负载均衡是确保整个系统运行顺畅的重要组成部分。它有助于避免单点故障,提高系统的可用性,并允许系统根据需求自动扩展。选择适当的负载均衡策略和工具对于构建稳健的微服务系统至关重要。

5.2 自动负载均衡

Gateway还提供了和Zuul类似的自动路由规则,具体配置如下:

  1. gateway.discovery.locator.enabled = true 这个配置默认为false,但是如果设置为true就是开启了通过serviceID转发到具体的服务实例。
  2. 配置好之后,可以直接通过服务名称来进行访问Nacos中注册的服务和对应接口。
  3. Gateway在开启了自动路由之后还自带负载均衡功能。
server:
  port: 9999

spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true # 开启自动路由功能,根据服务名自动创建routes
  • 测试:[http://localhost:9999/nacos-provider/info/1]

    我们直接通过spring gateway的服务地址和服务提供者nacos-provider的服务名组成的url地址,就可以以负载均衡的方式访问nacos-provider的服务。

5.3 手动负载均衡

自动负载均衡存在一个问题就是需要暴露每一个服务的服务名称,因此可以采用手动负载均衡的方式来避免暴露微服务的服务名称。

  • yml配置:
server:
  port: 9999

spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: nacos-provider
          uri: lb://nacos-provider # 开启负载均衡,服务名称为nacos-provider
          predicates: # 断言,放开所有路径
            - Path=/**
  • lb:// 代表开启负载均衡
  • 测试:[http://localhost:9999/info/1]

6. Gateway断言Predicate

Gateway断言可以理解为当满足条件后才会进行转发,总结就是Predicate就是为了实现一组匹配规则,让请求过来找到相应的Route进行处理。

6.1 断言种类

Spring Cloud Gateway支持多种路由断言(Route Predicates)类型,用于匹配和路由HTTP请求。以下是一些常见的路由断言类型:

  1. Path Route Predicate(路径匹配):根据请求的路径进行匹配。

predicates:

  • Path=/api/**

这将匹配所有以/api/开头的路径。

  1. Host Route Predicate(主机匹配):根据请求的主机名进行匹配。

predicates:

  • Host=example.com

这将匹配主机名为example.com的请求。

  1. Method Route Predicate(HTTP方法匹配):根据HTTP请求方法进行匹配。

predicates:

  • Method=GET

这将匹配HTTP GET请求。

  1. Header Route Predicate(请求头匹配):根据请求头信息进行匹配。

predicates:

  • Header=Authorization, Bearer .+

这将匹配包含Authorization头且值以Bearer开头的请求。

  1. Query Route Predicate(查询参数匹配):根据请求的查询参数进行匹配。

predicates:

  • Query=name, john

这将匹配包含name=john的查询参数的请求。

  1. Cookie Route Predicate(Cookie匹配):根据请求的Cookie信息进行匹配。

predicates:

  • Cookie=sessionId, .+

这将匹配包含名为sessionId的Cookie的请求。

  1. Combining Predicates(组合匹配):你可以组合多个路由断言来创建更复杂的匹配条件。

predicates:

  • Path=/api/**
  • Host=example.com

这将匹配主机为example.com且路径以/api/开头的请求。

这些路由断言允许你根据请求的不同属性(如路径、主机、请求头、HTTP方法等)进行匹配和路由,从而更灵活地控制请求的路由和处理。你可以在Spring Cloud Gateway的路由配置中定义这些路由断言,以满足你的具体需求。

7. Gateway的Filter

路由过滤器允许以某种方式修改传入的http请求或传出的HTTP响应,路由过滤器的范围是特定的路由Spring Cloud Gateway包含许多内置的Gateway Filter工厂。

7.1 内置Filter

7.1.1 内置过滤器分类

Gateway内置的Filter生命周期分为两种:pre(业务逻辑之前)、post(业务逻辑之后)

Gateway本身自带的Filter分为2种:GateWayFilter(单一)、GlobalFilter(全局)

Spring Cloud Gateway提供了多个内置的过滤器(Filters),这些过滤器允许你在请求和响应的生命周期中执行各种操作,例如请求路由、修改请求和响应、增加头信息等。以下是一些常见的内置过滤器:

  1. Forward Routing Filter:用于路由请求到后端服务。

  2. LoadBalancerClient Filter:通过LoadBalancerClient执行负载均衡请求。

  3. AddRequestHeader Filter:在请求中添加头信息。

  4. AddRequestParameter Filter:在请求中添加查询参数。

  5. RewritePath Filter:重写请求路径,用于修改请求的路径。

  6. SetStatus Filter:设置HTTP响应状态码。

  7. AddResponseHeader Filter:在响应中添加头信息。

  8. Hystrix Filter:用于Hystrix断路器的支持。

  9. WebSockets Filter:用于WebSocket代理。

  10. ModifyResponseBody Filter:修改响应体内容。

  11. PreserveHostHeader Filter:保留原始主机头信息。

  12. RequestRateLimiter Filter:实现请求速率限制。

这些内置过滤器可以通过Spring Cloud Gateway的路由配置文件进行配置,从而对请求和响应进行自定义处理。你可以根据具体需求组合和配置这些过滤器,以满足你的应用程序的需求。此外,你也可以编写自定义过滤器来执行更高度定制的操作。过滤器在Gateway中扮演了非常重要的角色,帮助你实现请求的路由和处理逻辑。

7.1.2 内置过滤器配置

Spring Gateway提供了许多内置的过滤器,用于执行常见的网关任务,例如鉴权、请求转发、重定向等。你可以在Spring Gateway的配置中添加这些内置过滤器来满足你的需求。以下是如何配置内置过滤器的一些示例:

  1. 鉴权过滤器:用于对请求进行身份验证和授权,你可以使用AddRequestHeader过滤器来添加认证信息到请求头中。
spring:
  cloud:
    gateway:
      default-filters:
        - name: AddRequestHeader
          args:
            X-Request-Auth: some-auth-token

3. 重定向过滤器:用于将请求重定向到其他路径或URL。你可以使用RedirectTo过滤器来执行重定向操作。

spring:
  cloud:
    gateway:
      routes:
        - id: my_redirect_route
          uri: http://example.com
          predicates:
            - Path=/redirect
          filters:
            - RedirectTo=302:http://new-location.com

4. 请求转发过滤器:用于将请求转发到其他服务或路径。你可以使用ForwardTo过滤器来执行请求转发。

spring:
  cloud:
    gateway:
      routes:
        - id: my_forward_route
          uri: http://example.com
          predicates:
            - Path=/forward
          filters:
            - ForwardTo=http://forward-service.com

5. 添加响应头过滤器:用于在响应中添加额外的头信息。你可以使用AddResponseHeader过滤器来添加响应头。

spring:
  cloud:
    gateway:
      default-filters:
        - name: AddResponseHeader
          args:
            X-Response-Header: some-value

这只是一些内置过滤器的示例,Spring Gateway提供了更多的内置过滤器,你可以根据你的需求在配置中使用它们。通过合理配置内置过滤器,你可以实现许多常见的网关功能,而无需自行编写复杂的逻辑。

7.2 自定义Filter

要创建自定义过滤器(Custom Filter)来扩展Spring Cloud Gateway的功能,你需要遵循一些步骤。自定义过滤器可以用于执行各种自定义操作,例如鉴权、日志记录、修改请求和响应等。以下是创建自定义过滤器的一般步骤:

  • 创建一个自定义过滤器类:首先,你需要创建一个Java类,实现GatewayFilterGlobalFilter接口。这两个接口分别用于创建局部过滤器和全局过滤器。

  • 局部过滤器 (GatewayFilter) 会应用于特定路由的请求。

  • 全局过滤器 (GlobalFilter) 会应用于所有路由的请求。

下面我们以创建一个全局过滤器来展示如何创建自定义过滤器,要创建自定义的全局过滤器,你需要实现Spring Cloud Gateway的 GlobalFilter 接口。以下是创建一个简单的全局自定义过滤器的步骤:

  1. 创建一个类,实现 GlobalFilter 接口。

  2. 在该类上添加 @Component 注解,以便Spring容器可以扫描并管理它。

  3. 实现 filter 方法,该方法包含你自定义过滤器的逻辑。

以下是一个示例自定义全局过滤器的代码:

import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono&lt;Void&gt; filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 在请求处理之前执行自定义逻辑
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 在响应中添加自定义的HTTP头
        response.getHeaders().add("X-Custom-Header", "CustomHeaderValue");

        // 修改请求或响应内容
        ServerHttpRequest modifiedRequest = request.mutate()
                .header("X-Modified-Header", "ModifiedValue")
                .build();
        ServerWebExchange modifiedExchange = exchange.mutate()
                .request(modifiedRequest)
                .build();

        // 执行链中的下一个过滤器或处理器
        return chain.filter(modifiedExchange).then(Mono.fromRunnable(() -&gt; {
            // 在请求处理完成后执行自定义逻辑
            // 这里可以对响应进行进一步处理
        }));
    }

    @Override
    public int getOrder() {
        // 指定过滤器的执行顺序,可以是负数、零、正数,数字越小,执行顺序越靠前
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

在上面的示例中,CustomGlobalFilter 是一个全局过滤器,它在请求处理前和请求处理后执行自定义逻辑。你可以在 filter 方法中访问请求、响应,修改它们的内容,添加自定义HTTP头,以及执行其他自定义逻辑。getOrder 方法用于指定过滤器的执行顺序,数字越小,执行顺序越靠前。

确保将 CustomGlobalFilter 类放在Spring Boot应用程序的类路径下,Spring会自动识别并应用它。这样,你的自定义全局过滤器就会在请求到达Spring Cloud Gateway时生效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/123460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么GAN生成对抗网络?生成对抗网络可以干什么?

生成对抗网络(Generative Adversarial Nets,简称GAN)。神经网络分很多种,有普通的前向传播网络,有分析图片的CNN卷积神经网络,有分析系列化数据比如语言、文字的RNN循环神经网络,这些神经网络都是用来输入数据,得到想要的结果,我们看中的是这些神经网络中很好地将数据与…

SpringCloud——消息总线——Bus

1.什么是总线&#xff1f; 我们在微服务的项目中&#xff0c;通常会构建一个共同的消息主题&#xff0c;然后需要的服务可以连接上来&#xff0c;该主题中产生的消息会被监听和消费&#xff0c;这种我们称为消息总线。 SpringCloud Bus 配合SpringCloud Config使用可以实现配置…

RestTemplate配置和使用

在项目中&#xff0c;如果要调用第三方的http服务&#xff0c;就需要发起http请求&#xff0c;常用的请求方式&#xff1a;第一种&#xff0c;使用java原生发起http请求&#xff0c;这种方式不需要引入第三方库&#xff0c;但是连接不可复用&#xff0c;如果要实现连接复用&…

基础课26——业务流程分析方法论

基础课25中我们提到业务流程分析方法包括以下几种&#xff1a; 价值链分析法&#xff1a;主要是找出或设计出哪些业务能够使得客户满意&#xff0c;实现客户价值最大化的业务流程。要进行价值链分析的时候可以从企业具体的活动进行细分&#xff0c;细分的具体方面可以从生产指…

运行springboot时提示:源值 7 已过时,将在未来版本中删除,并且提示java.time not exist, LocaDateTime类找不到。

运行springboot时提示&#xff1a;源值 7 已过时&#xff0c;将在未来版本中删除&#xff0c;并且提示 java.time not exist, LocaDateTime类找不到。 解决方法&#xff1a; 方式一&#xff1a;通过IDEA修改这几个地方的JDK版本 1&#xff09;打开ProjectStructure->Proj…

多篇论文介绍-Wiou

论文地址 目录 https://arxiv.org/pdf/2301.10051.pdf 01 CIEFRNet&#xff1a;面向高速公路的抛洒物检测算法 02改进 YOLOv5 的 PDC 钻头复合片缺损识别 03 基于SimAM注意力机制的DCN-YOLOv5水下目标检测 04 基于改进YOLOv7-tiny 算法的输电线路螺栓缺销检测 05 基于改…

机器学习中的假设检验

正态性检验相关分析回归分析 所谓假设检验&#xff0c;其实就是根据原假设来构造一种已知分布的统计量来计算概率&#xff0c;根据概率值大小来判断能否拒绝原假设&#xff0c;从而得到一种结论。假设检验的过程就是&#xff0c;构造一个原假设成立条件下的事件A&#xff0c;计…

基于斑马算法的无人机航迹规划-附代码

基于斑马算法的无人机航迹规划 文章目录 基于斑马算法的无人机航迹规划1.斑马搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用斑马算法来优化无人机航迹规划。 1.斑马搜索算法 …

内网可达网段探测netspy- Mac环境

netspy是一款快速探测内网可达网段工具 当我们进入内网后想要扩大战果&#xff0c;那我们可能首先想知道当前主机能通哪些内网段。 netspy正是一款应用而生的小工具&#xff0c;体积较小&#xff0c;速度极快&#xff0c;支持跨平台&#xff0c;支持多种协议探测&#xff0c;…

软件测试/校招推荐丨鼎捷软件股份有限公司岗位开放

点此获取更多相关资料 软件测试工程师 岗位职责 负责公司产品的日常测试工作&#xff1b;依据软件需求和非功能需求&#xff0c;编写测试方案和测试用例&#xff0c;设计测试脚本&#xff1b;负责服务器系统和软件的日常维护工作&#xff0c;为上线部署和运维活动提供技术支持…

HarmonyOS应用开发

引言 本章将深入探讨 HarmonyOS 应用开发的关键方面&#xff0c;包括应用的生命周期、数据存储和网络访问。了解这些内容对于创建功能丰富、高效的 HarmonyOS 应用至关重要。 目录 HarmonyOS 应用的生命周期HarmonyOS 应用的数据存储HarmonyOS 应用的网络访问总结 1. Harmo…

python 时间加法 输出t分钟后的时间

题目&#xff1a; 现在时间是a点b分&#xff0c;请问t分钟后&#xff0c;是几点几分&#xff1f; 输入&#xff1a; 第一行包含一个整数a 第二行包含一个整数b 第三行包含一个整数t 其中&#xff0c;0≤a≤23&#xff0c;0≤b≤59&#xff0c;0≤t&#xff0c;t分钟后还…

【Linux】进程的基本概念和进程控制

TOC 目录 一.冯诺依曼体系结构 二. 操作系统(Operator System) 概念 设计OS的目的 定位 总结 系统调用和库函数概念 进程 基本概念 描述进程-PCB task_struct-PCB的一种 task_ struct内容分类 组织进程 查看进程 通过系统调用获取进程标识符 进程状态 D--深度…

Android内存回收机制、GC算法及内存问题分析解决

Android内存回收机制、GC算法及内存问题分析解决 在Android开发中&#xff0c;Java内存回收和垃圾收集&#xff08;GC&#xff09;机制是确保应用程序高效运行的关键部分。针对不同对象存活率&#xff0c;Android平台采用了引用计数算法和可达性分析法来判定对象的可回收性&am…

【代码随想录】算法训练营 第二十天 第六章 二叉树 Part 6

654. 最大二叉树 题目 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回…

IntelliJ IDEA 2023.2.1 (Ultimate Edition) 版本 Git 如何合并多次的本地提交进行 Push

本心、输入输出、结果 文章目录 IntelliJ IDEA 2023.2.1 (Ultimate Edition) 版本 Git 如何合并多次的本地提交进行 Push前言为什么需要把多次本地提交合并合并提交的 2 种形式:事中合并、事后合并事中合并事后合并:支持拆分为多组提交弘扬爱国精神IntelliJ IDEA 2023.2.1 (U…

Android Camera App启动流程解析

前言&#xff1a;做了7年的camera app开发&#xff0c;给自己一个总结&#xff0c;算是对camera的一次告白吧。Camera被大家誉为手机的眼睛&#xff0c;是现在各大手机厂商的卖点&#xff0c;也是各大厂商重点发力的地方。Camera的重要性我就不在这里赘述了&#xff0c;让我们进…

【跟小嘉学习JavaWeb开发】第一章 开发环境搭建

系列文章目录 【跟小嘉学习JavaWeb开发】第一章 开发环境搭建 文章目录 系列文章目录[TOC](文章目录) 前言一、JDK的下载与安装1.1、关于JDK的版本问题 二、环境变量配置2.1、配置 JAVA_HOME、CLASSPATH2.2、配置path2.3、启动 cmd 三、编写代码、编译并执行3.1、编写代码&…

输出所有最长公共子序列

输出所有最长公共子序列 什么是最长公共子序列过程讲解完整程序代码&#xff08;python&#xff09; 什么是最长公共子序列 在力扣题库中的1143题有一道最长公共子序列&#xff0c;但是那个只是返回最长子序列的长度&#xff0c;而没有输出所有的最长子序列 通过上图中的举例…

Python制作采集直播弹幕小软件

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用: Python 3.8 Pycharm模块使用: import requests >>> pip install requests import time import tkinter&#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;…