Spring Gateway基础知识总结

news2024/12/23 20:21:39

本文主要总结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时生效。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编程知识\_C与汇编深入分析

1. 汇编怎么调用C函数 1.1 直接调用 bl main 1.2 想传参数怎么办&#xff1f; 在arm中有个ATPCS规则(ARM-THUMB procedure call standard&#xff08;ARM-Thumb过程调用标准&#xff09;。 约定r0-r15寄存器的用途&#xff1a; r0-r3 调用者和被调用者之间传参数 r4-r11 函…

ARM寄存器及功能介绍/R0-R15寄存器

1、ARM 寄存器组介绍 ARM 处理器一般共有 37 个寄存器&#xff0c;其中包括&#xff1a; &#xff08;1&#xff09; 31 个通用寄存器&#xff0c;包括 PC&#xff08;程序计数器&#xff09;在内&#xff0c;都是 32 位的寄存器。 &#xff08;2&#xff09; 6 个状态寄存器…

Linux学习笔记--高级

Shell概述 1&#xff0c;shell概述 是一个c语言编写的脚本语言&#xff0c;是linux和用户的桥梁&#xff0c;用户输入命令交给shell处理。shell&#xff0c;将相应的操作传递给内核&#xff08;kernel&#xff09;&#xff0c;内核把处理的结果输出给用户 1.1Shell解释器有哪…

oled显示器程序(IIC)从stm32f103移植到stm32f429出现bug不显示-解决移植失败问题

出现问题处&#xff1a; 刚开始更换了这两行代码&#xff0c;然后更换位置后&#xff0c;oled正常显示&#xff0c;如下为正确顺序 I2C_Configuration();//配置CPU的硬件I2COLED_Init();//OLED初始化 在这段代码中&#xff0c;I2C_Configuration() 函数用于配置CPU的硬件 I2C…

阶段七-Day02-Spring02

一、Spring的注解支持 1. 为什么使用Spring注解 在昨天的练习中有这样的一段代码&#xff0c;为了给UserServiceImpl注入UserMapper对象。 2. Spring支持的注解&#xff08;IoC/DI相关&#xff09; 下面Repository、Service、Controller、Configuration都是Component注解的…

阴虱是怎么长出来的?皮肤性病科主任谭巍讲述五大因素

阴虱&#xff0c;是一种皮肤接触性传染性寄生虫病&#xff0c;在卫生情况不好的前提下有感染阴虱的可能性。人在感染阴虱后会对身心健康带来负面影响&#xff0c;所产生的临床症状会直接影响感染者的工作生活&#xff0c;所以日常应注意预防阴虱病。 然而&#xff0c;到现在还…

JS逆向爬虫---响应结果加密⑤【token参数加密与DES解密】

https://spa7.scrape.center/ 文本数据 数据内嵌在js内,普通合理请求即可获取 图片 位于固定接口 类似https://spa7.scrape.center/img/durant.png 固定url名称 Token 参数确定 base64Name > base64编码后的中文名称 nodejs 代码 //导入crypto-js模块 var CryptoJS…

Spring笔记(四)(黑马)(web层解决方案-SpringMVC)

01、Spring MVC 简介 1.1 SpringMVC概述 SpringMVC是一个基于Spring开发的MVC轻量级框架&#xff0c;Spring3.0后发布的组件&#xff0c;SpringMVC和Spring可以无 缝整合&#xff0c;使用DispatcherServlet作为前端控制器&#xff0c;且内部提供了处理器映射器、处理器适配器…

ONP: Error #15: Initializing libiomp5md.dll【报错系列】

问题如下&#xff1a; 解决方案&#xff1a; 譬如我的就是这个&#xff1a; 删掉&#xff0c;再回去运行即可。

web应用程序、Django框架的学习

web应用程序 什么是web? Web应用程序是一种可以通过Web访问的应用程序,用户只需要有浏览器即可&#xff0c;不需要再安装其他软件 案例&#xff1a; 淘宝网、京东网、博客园、等都是基于web应用的程序 应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序&#xff0c…

Oracle Primavera Unifier 23.10 新特征

根据官方的说法&#xff0c;Unifier 23.7 ~ 23.9 更多为对功能bug的修复&#xff0c;以下将对23.10进行重点介绍 Cost Sheets Cost Sheets Support Conditional Formatting Conditional formatting of table data is now supported in cost sheets with features such as ce…

微信公众号全流程

申请公众号&#xff08;服务号已认证&#xff09;web开发者工具中绑定开发人员&#xff08;该开发人员需要关注1中申请的公众号&#xff09;基本配置 3.1 服务器配置 URL&#xff1a;验证服务器&#xff08;后端写的验证服务器的接口&#xff09; 后端代码&#xff1a;egg.js …

杂货铺 | citespace的使用

安装教程 【CiteSpace保姆级教程1】文献综述怎么写&#xff1f; &#x1f4da;数据下载 1. 新建文件夹 2. 数据下载 知网高级检索 数据选中导出 &#xff1a;一次500 导出后重命名为download_xxx.txt&#xff0c;放到input文件里 3. 数据转换 把output里的数据复制到data里…

【算法与数据结构】17、LeetCode电话号码的字母组合

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题需要解决的问题有三个&#xff1a; 一、如何实现数字到字母的映射二、如何实现组合问题三、如何解…

移远EC600U-CN开发板 day03

控件探索-按钮&#xff08;lv.btn&#xff09; (1) 创建并显示一个按钮 * 核心代码 btn lv.btn(scr) #将按钮与src对象关联 btn.align(lv.ALIGN.CENTER,0,0) #居中显示&#xff08;第1个0表示x的偏移量&#xff0c;第2个0表示相对于y的偏移量&#xff09; label lv.l…

万字长文 - Python 日志记录器logging 百科全书 之 基础配置

万字长文 - Python 日志记录器logging 百科全书 之 基础配置 前言 在日常的开发中工作中&#xff0c;日志记录扮演着不可或缺的角色。它不仅能让我们了解应用程序的运行状况&#xff0c;还能帮助我们定位并解决各种问题。 最基本的&#xff0c;它记录了应用程序的运行情况&am…

说话人识别声纹识别CAM++,ECAPA-TDNN等算法

参考:https://www.modelscope.cn/models?page=1&tasks=speaker-verification&type=audio https://github.com/alibaba-damo-academy/3D-Speaker/blob/main/requirements.txt 单个声纹比较可以直接modelscope包运行 from modelscope.pipelines import pipeline sv_pi…

阿里云2023年双十一低至87/年

阿里云ECS11月销量王 99元/年 活动时间 2023年10月31日0点0分0秒至2026年3月31日23点59分59秒&#xff1b; 点击活动场地&#xff1a; 活动对象 满足以下全部条件的阿里云用户&#xff1a; 1、阿里云注册会员用户&#xff1b; 2、完成阿里云企业认证或个人认证用户&#xff1b…

学习Nginx配置

1.下载地址 官网地址&#xff1a;NGINX - 免费试用、软件下载、产品定价 (nginx-cn.net) 我这边选择NGINX 开源版 nginx: download 2.nginx的基本配置 配置文件语法 配置文件组成&#xff1a;注释行&#xff0c;指令块配置项和一系列指令配置项组成。 单个指令组成&#x…

自动控制原理--面试问答题

以下文中的&#xff0c;例如 s_1 为 s下角标1。面试加油&#xff01; 控制系统的三要素&#xff1a;稳准快。稳&#xff0c;系统最后不能震荡、发散&#xff0c;一定要收敛于某一个值&#xff1b;快&#xff0c;能够迅速达到系统的预设值&#xff1b;准&#xff0c;最后稳态值…