Spring Cloud Gateway 入门与实战

news2024/9/23 21:25:18

一、网关

在微服务框架中,网关是一个提供统一访问地址的组件,它充当了客户端和内部微服务之间的中介。网关主要负责流量路由和转发,将外部请求引导到相应的微服务实例上,同时提供一些功能,如身份认证、授权、限流、监控、日志记录等。

二、网关作用

  1. 路由功能:网关可以根据目标地址的不同,选择最佳的路径将数据包从源网络路由到目标网络。它通过维护路由表来确定数据包的转发方向,并选择最优的路径。
  2. 安全控制:网关可以实施网络安全策略,对进出的数据包进行检查和过滤。它可以验证和授权来自源网络的数据包,并阻止未经授权的访问。防火墙是一种常见的网关设备,用于过滤和保护网络免受恶意攻击和未经授权的访问。
  3. 协议转换:不同网络使用不同的通信协议,网关可以进行协议转换,使得不同网络的设备可以互相通信。例如:将HTTPS 协议转换成 HTTP 协议。
  4. 网络地址转换(NAT):网关可以执行网络地址转换,将内部网络使用的私有 IP 地址转换为外部网络使用的公共 IP 地址,以实现多台计算机共享一个公共 IP 地址上网

三、Spring Cloud Gateway 组成 

  1. 路由:定义了请求应该被转发到哪个目标地址。路由由 ID、目标 URI 、断言、和过滤器组成。通过配置多个路由,可以实现不同请求的路由规则。
  2. 断言:用于匹配请求条件,如果请求匹配断言条件,则会被映射到对应目标地址上。断言可以基于请求的路径、请求头、请求参数等信息进行匹配。
  3. 过滤器:用于在请求路由前或路由后进行一些处理,如添加头部信息、修改请求体等。过滤器可以在全局范围或特定路由范围内配置,多个路由器可以组成过滤器链。

四、Spring Cloud Gateway 的使用

使用步骤如下:

1. 添加 Gateway 依赖

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

2. 设置网关路由规则

spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: http://192.168.146.1:8082 #映射的ip和端口
        predicates:
        - Path=/user/**,/log/** #当请求路径满足配置的path时,将ip和端口映射到上面的uri

五、断言(Predicate)类型

Spring Cloud Gateway 支持的断言类型目前有 12 中, 包含以下这些:

1. 根据时间匹配:

  • After: 请求在指定时间之后才匹配
  • Before:请求在指定时间之前才匹配
  • Between:请求在指定时间中间才匹配

2. Cookie:匹配求中的Cookie值

3. Header:匹配请求中的 Header 值

4. Host:匹配请求中的 Host 值

5. Method:匹配请求头中的 Method 的值

6. Path:匹配请求路径

7. Query:匹配请求参数

8. RemoteAddr:匹配请求的 IP 地址,支持 IPV4 和 IPV6

9. Weight:根据权重来分发请求,权重根据 group 来计算

10. XForwardedRemoteAddr:根据 X-Forwarded-For 匹配

5.1 根据时间匹配

spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: http://192.168.146.1:8082
        predicates:
        - Path=/user/**,/log/**
        - Before=2024-07-15T19:00:00.000+08:00[Asia/Shanghai] #上海时间2024-7-15 19点前允许访问

between

spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: http://192.168.146.1:8082
        predicates:
        - Path=/user/**,/log/**
        - Between=2024-07-13T19:00:00.000+08:00[Asia/Shanghai],2024-07-15T19:00:00.000+08:00[Asia/Shanghai] #上海时间2024-7-13 19点 ~ 2024-7-15 19点之间允许访问

5.2 根据 Header 匹配

spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: http://192.168.146.1:8082
        predicates:
        - Path=/user/**,/log/**
        - Between=2024-07-13T19:00:00.000+08:00[Asia/Shanghai],2024-07-15T19:00:00.000+08:00[Asia/Shanghai] #上海时间2024-7-15 19点前允许访问
        - Header= Ip2contry,\w+ 

其中 "Ip2contry" 表示 Header 中的 key ,而 ”\w+“ 表示的是key 的值,值可用正则表达式进行匹配

5.3 根据 Cookie 匹配

spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: http://192.168.146.1:8082
        predicates:
        - Path=/user/**,/log/**
        - Between=2024-07-13T19:00:00.000+08:00[Asia/Shanghai],2024-07-15T19:00:00.000+08:00[Asia/Shanghai] #上海时间2024-7-15 19点前允许访问
        - Header= Ip2contry,\w+
        - Cookie= author,zhangsan

5.4 根据 weight 进行配置 

spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: http://169.254.165.28:8081
        predicates:
        - Weight=group2,10
      - id: user-service2
        uri: http://169.254.165.28:8082
        predicates:
        - Weight=group2,90

group2 表示分组,10 表示所在分组所占权重

六、Spring Cloud Gateway + Nacos + LoadBalancer 实现企业级网关

6.1 添加依赖

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<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-gateway</artifactId>
</dependency>

6.2 设置路由规则

spring:
  cloud:
    gateway:
      routes:
      - id: user-service
        uri: lb://user-service #user-service #调用服务注册在 nacos 中的名称
        predicates:
        - Path=/user/**
    nacos:
      discovery:
        server-addr: localhost:8848
        password: nacos
        username: nacos
        register-enabled: false

七、过滤器

过滤器作用:

  • 功能扩展和定制:过滤器可以用于对现有功能进行扩展和定制。通过拦截和处理数据流或事件流,可以修改数据,增加额外的功能逻辑,实现特定的业务需求。例如,可以使用过滤器在请求之前进行身份验证、权限控制,或者在响应之后进行日志记录、数据转换等操作。
  • 数据校验和过滤:过滤器可以用于对数据进行校验和过滤。在接收到数据之后,可以使用过滤器对数据进行检查,验证数据的合法性,过滤掉无效或不符合要求的数据。这有助于保证数据的准确性、完整性和安全性。
  • 安全保护:过滤器可以用于提供安全保护措施,可以使用过滤器对输入的请求进行检查和清洗,以防止潜在的安全漏洞,例如跨站脚本攻击(XSS)、跨站请求伪造(CSRF) 等攻击。过滤器还可以进行访问控制,验证权限和实施安全策略。
  • 性能优化:过滤器可以用于性能优化。例如,在数据处理流水线中,可以使用过滤器对数据进行转换、过滤或缓存,以提高处理速度和效率。过滤器还可以用于数据压缩、缓存预热等场景,减少数据传输和处理的成本。
  • 统一处理和逻辑服用:过滤器提供了一种统一的处理方式,可以在不同的组件或模块上应用相同的逻辑或处理方式。通过将处理逻辑抽象为过滤器,可以避免重复代码、统一错误处理和统一异常处理等,提高代码复用性和可维护性。

7.1 内置局部过滤器

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-demo
        uri: lb://user-service
        predicates:
        - Path=/user/**
        filters:
        - AddResponseHeader=soruce,userservice

其中 "AddResponseHeader" 表示添加返回头过滤器,前面的值 " source" 为 key ,后面的值 "value" 为 value

7.2 AddRequestHeader

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-demo
        uri: lb://user-service
        predicates:
        - Path=/user/**
        filters:
        - AddResponseHeader=soruce,userservice
        - AddRequestHeader= my-request-market, kaikai

在下游服务调用接口中打印所有的 Header 查看添加的 Header 信息,代码如下:

@RequestMapping("/getHeader")
public void getHeader(HttpServletRequest request){
    Enumeration<String> headers= request.getHeaderNames();
    while (headers.hasMoreElements()){
        String key=headers.nextElement();
        String value= request.getHeader(key);
        System.out.println(key+ " : "+value);
    }
}

7.3 AddRequestParameter

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-demo
        uri: lb://user-service
        predicates:
        - Path=/user/**
        filters:
        - AddRequestParameter= id,209

后续请求中带有key为id,value 209 的参数

    @RequestMapping("/getID")
    public Integer getID(@RequestParam("id")Integer id){
        return id;
    }

    @RequestMapping("/getId")
    public String getId(HttpServletRequest request){
        return request.getParameter("id");
    }

7.4 PrefixPath

在请求的 url 前面添加前缀,例如请求的是 /user, 添加了 PrefixPath为 /new,那么后续访问的地址就为 "/new/user"

7.5 限流过滤器- RequestRateLimiter

网关限流过滤器,Spring Cloud Gateway 内置了限流功能,它使用的限流算法是令牌桶的限流算法

令牌桶限流算法:令牌安固定的速率被放入令牌桶中,桶中最多存放 N个令牌(Token),当桶装满时,新添加的令牌被丢弃或拒绝。当请求到达时,将从桶中删除 1 个令牌。令牌中的令牌不仅可以被移除,还可以往里添加,所以为了保证接口随时有数据通过,必须不停地往桶里加令牌。由此可见,往桶里加令牌的速度就决定了数据通过接口的速度。我们通过控制往令牌桶里加令牌的速度从而控制接口的流量。

Spring Cloud Gateway 当前版本支持 和 Redis 一起实现限流功能,它的实现步骤总共分为以下三步:

1. 添加 Reids 框架依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

 2. 创建限流规则

创建一个类,根据 IP 进行限流:

@Component
public class IpKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        System.out.println(exchange.getRequest().getRemoteAddress().getHostString());
        System.out.println(exchange.getRequest().getRemoteAddress().getHostName());
        return Mono.just(exchange.getRequest().getRemoteAddress().getHostString());
    }
}

3. 配置限流规则

在项目的配置文件中,配置以下内容:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-demo
        uri: lb://user-service
        predicates:
        - Path=/user/**
        filters:
          - name: RequestRateLimiter
            args:
               redis-rate-limiter.replenishRate: 1
               redis-rate-limiter.burstCapacity: 1
               keyResolver: '#{@ipKeyResolver}'
    nacos:
      discovery:
        username: nacos
        password: nacos
        server-addr: localhost:8848
  data:
    redis:
      host: 114.115.149.19
      port: 6378
      database: 0

其中,name 必须等于 "RequestRateLimiter" 内置限流过滤器,其他参数:

  • redis-rate-limiter.replenishRate:令牌填充速度:每秒允许请求数
  • redis-rate-limiter.burstCapacity:  令牌桶容量:最大令牌数
  • redis-rate-limiter.requestedTokens: 每次请求消耗的令牌数
  • keyResolver: 根据哪个 key 进行限流,它的值时 spEL 表达式。

7.6 Retry

配置:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-demo
        uri: lb://user-service
        predicates:
        - Path=/user/**
        filters:
        - name: Retry
          args:
            retries: 3 #重试次数
            statuses: Gateway Timeout #状态码,详情参考 HttpResponseStatus.class
            method: GET
#            series: CLIENT_ERROR
            backoff:
              firstBackoff: 1000ms #第一次重试间隔
              maxBackoff: 10000ms   #最大重试间隔时间
              factor: 2 #firstBackoff * (factor ^ n) 重试系数,如果重试间隔时间超过最大重试间隔时间,按照最大重试间隔时间来算
              basedOnPreviousValue: false #根据上次重试时间加上重试系数来计算

代码调试:

    @RequestMapping("/getstatus")
    public void getStatus(HttpServletResponse response){
        System.out.println("==============Do GetStatus Method ===================");
        response.setStatus(403);
    }
  • name :一定要等于 "Retry" ,因为 "Retry" 就是内置的过滤器的名字
  • retries: 重试次数
  • statuses:状态码 ,匹配对应状态码响应,并重试
  • series: 状态码配置,符合某段状态码才会进行重试逻辑,默认值是SERVER_ERROR,值是 5 ,也就是 5XX 开头的状态码。
    1XX:INFORMATIONAL
    2XX:SUCCESSFUL
    3XX:REDIRECTION
    4XX:CLIENT_ERROR
    5XX:SERVER_ERROR
  • backoff:重试指数配置策略,默认关闭

注:statuses 和 retries 是且的关系。

7.7 内置全局过滤器

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-demo
        uri: lb://user-service
        predicates:
        - Path=/user/**
        filters:
#        - AddResponseHeader=soruce,userservice
      default-filters:
        - AddResponseHeader=soruce,userservice

7.8 自定义过滤器

package com.gatewayservicesoa.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
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 AuthFilter implements GlobalFilter, Ordered {
    /**
     * @param exchange 要执行的事件
     * @param chain    过滤器链
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //此处使用的是相应试 HTTP
        ServerHttpRequest request=  exchange.getRequest();
        ServerHttpResponse response=  exchange.getResponse();
        if(request.getQueryParams().getFirst("name")!=null && request.getQueryParams().getFirst("name").equals("name")
                && request.getQueryParams().getFirst("password")!=null && request.getQueryParams().getFirst("password").equals("123")){
            return chain.filter(exchange);
        }else {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
    }

    @Override
    public int getOrder() {
        //过滤器的执行顺序,值越小,越早执行
        return 0;
    }
}

八、工作原理

客户但向 Spring Cloud Gateway 发出请求,网关映射处理程序(Gateway Handler Mapping) 会根据请求路径进行路由匹配,然后再将其发送到网关 Web 处理器(Gateway Web Handler) 进行处理。此时处理器会经过过滤链(filter) 进行处理,而过滤器又分为 前置过滤器和后置过滤器,之后才会将请求发送给目标服务(也称代理的服务)。

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

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

相关文章

【企业级监控】Zabbix监控MySQL主从复制

Zabbix自定义监控项与触发器 文章目录 Zabbix自定义监控项与触发器资源列表基础环境前言四、监控MySQL主从复制4.1、部署mysql主从复制4.1.1、在两台主机&#xff08;102和103上安装&#xff09;4.1.2、主机102当master4.1.3、主机103当slave 4.2、MySQL-slave端开启自定义Key值…

JMeter案例分享:通过数据验证的错误,说说CSV数据文件设置中的线程共享模式

前言 用过JMeter参数化的小伙伴&#xff0c;想必对CSV Data Set Config非常熟悉。大家平时更关注变量名称&#xff0c;是否忽略首行等参数&#xff0c;其余的一般都使用默认值。然而我最近遇到一个未按照我的预想读取数据的案例&#xff0c;原因就出在最后一个参数“线程共享模…

摄像头 RN6752v1 视频采集卡

摄像头 AHD倒车摄像头比较好&#xff0c;AHD英文全名Analog High Definition&#xff0c;即模拟高清&#xff0c;拥有比较好的分辨率与画面质感。 RN6752v1 GQW AKKY2 usb 采集卡 FHD&#xff08;1080p&#xff09;、HD&#xff08;720p&#xff09;和D1&#xff08;480i&am…

开始Linux之路

人生得一知己足矣&#xff0c;斯世当以同怀视之。——鲁迅 Linux操作系统简单操作指令 1、ls指令2、pwd命令3、cd指令4、mkdir指令(重要)5、whoami命令6、创建一个普通用户7、重新认识指令8、which指令9、alias命令10、touch指令11、rmdir指令 及 rm指令(重要)12、man指令(重要…

C# Winform的三态CheckBox,以及批量修改Panel中的控件

在C# WinForms中&#xff0c;如果你想批量修改一个Panel容器内的所有CheckBox控件的状态&#xff0c;你可以使用foreach循环来遍历Panel的Controls集合。下面是一个示例&#xff0c;展示了如何将一个Panel内所有的CheckBox控件设为选中状态&#xff08;Checked true&#xff0…

借助 Aspose.Words,在 C# 中将 Word 转换为 JPG

有时我们需要将 Word 文档转换为图片&#xff0c;因为 DOC 或 DOCX 文件在不同设备上的显示可能会有所不同&#xff0c;但图像&#xff08;例如 JPG 格式&#xff09;在任何地方看起来都一样。 Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作…

超声波眼镜清洗机哪个牌子好?2024年超全热门眼镜清洗机推荐

夏天来了&#xff0c;在户外活动不到几分钟就已经大汗淋漓&#xff01;特别是汗珠一滴滴的挂在眼皮上往下坠落简直让戴眼镜的人苦不堪言&#xff01;虽说戴眼镜在现如今来看是非常普遍的一件事情&#xff0c;但是人们一直深受眼镜清洗的困扰&#xff01;很多朋友看到这里可能会…

C++学习日记 | Lecture 9 类基础

资料来源&#xff1a;南科大 余仕琪 C/C Program Design LINK&#xff1a; CPP/week09 at main ShiqiYu/CPP GitHub9.1-classes-and-objects_哔哩哔哩_bilibili9.2-constructors-and-destructors_哔哩哔哩_bilibili9.3-this-pointer_哔哩哔哩_bilibili9.4-const-and-static…

好用的《身份证工具》插件,解锁6大实用功能

在数据处理领域&#xff0c;超级处理器插件凭借其强大的功能和高效的性能&#xff0c;一直是Excel和WPS用户的心头好。而今&#xff0c;这一优秀插件再次迎来革新——身份证工具功能现已支持单独安装使用&#xff0c;为用户带来前所未有的便利与灵活性。 超级处理器下载与安装…

matlab入门学习

一、什么是matlab MATLAB&#xff08;matrix laboratory矩阵实验室&#xff09;是一款商用数学软件&#xff0c;主要面对科学计算、可视化以及交互式程序设计的高科技计算环境。可用于数据分析、深度学习、图像处理与计算机视觉、量化金融与风险管理等领域。 二、matlab和pyt…

快速在springboot项目中应用EasyExcel

目录 ​编辑一、介绍 二、准备工作 三、初始化项目 3.1 创建项目 3.2 引入依赖 3.3 创建数据库和数据表 3.4 编写application.properties文件 四、开始编写 4.1 目录结构 4.2 MyBatis配置类 4.3 用户实体类 4.4 mapper接口 4.5 编写数据操作文件 4.6 编写Service 业…

静态链接——编译和链接

一、编译和链接的过程 1、GCC生成可执行文件的总体过程 在日常的开发过程中&#xff0c;IDE总是会帮我们将编译和链接合并&#xff0c;一键式的执行,即使在liunx中&#xff0c;使用命令行来编译一个源文件也只是简单的一句"gcc hello.c"。我们并没有过多的关注编译和…

linux的学习(五):shell编程中的变量,运算符,条件判断

简介&#xff1a; shell编程的基本概念&#xff0c;定义变量&#xff0c;运算符&#xff0c;条件判断的基本使用 shell编程 把多个命令写到一个文件里&#xff0c;这个文件就是脚本&#xff0c;里面还有很多的流程控制 基本概念 脚本的后缀名是.sh 脚本的执行&#xff1a;…

全面理解Spring6框架到熟悉与掌握

个人笔记梳理&#xff0c;仅供参考 Spring是一款主流的JavaEE轻量级开源框架 Spring的狭义和广义 广义的Spring&#xff1a;Spring技术栈 泛指以Spring Framework为核心的Spring技术栈 经过十多年的发展&#xff0c;Spring已经不再是一个单纯的应用框架&#xff0c;而是逐…

EasyAnimate-v3版本支持I2V及超长视频生成

阿里云人工智能平台&#xff08;PAI&#xff09;自研开源的视频生成项目EasyAnimate正式发布v3版本&#xff1a; 支持 图片&#xff08;可配合文字&#xff09; 生成视频 支持 上传两张图片作为起止画面 生成视频 最大支持720p&#xff08;960*960分辨率&#xff09; 144帧视…

量化投资基础(一)之均值方差模型一

点赞、关注&#xff0c;养成良好习惯 Life is short, U need Python 量化投资基础系列&#xff0c;不断更新中 1. 投资组合收益率与风险 假设市场有 N N N 个资产&#xff0c;其随机收益率分别为 R 1 , R 2 , … , R N R_1,R_2,\dots,R_N R1​,R2​,…,RN​ &#xff0c;对应…

蓝桥 双周赛算法赛【小白场】

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;IT竞赛 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 蓝桥第14场小白入门赛T1/T2/T3 题目&#xff1a; T1照常还是送分题无需多…

【Git的基本操作】版本回退 | 撤销修改的三种情况 | 删除文件

目录 5.版本回退 5.1选项hard&后悔药 5.2后悔药&commit id 5.3版本回退的原理 6.撤销修改 6.1情况一 6.2情况二 6.3情况三 ​7.删除文件 Git重要能力之一马&#xff0c;版本回退功能。Git是版本控制系统&#xff0c;能够管理文件历史版本。本篇以ReadMe文件为…

STM32智能楼宇照明系统教程

目录 引言环境准备智能楼宇照明系统基础代码实现&#xff1a;实现智能楼宇照明系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;楼宇照明管理与优化问题解决方案与优化收尾与总结 1. 引言 智能楼宇照明系…

Vue3新特性:Teleport、Suspense玩转起来!

Vue3新特性&#xff1a;Teleport、Suspense玩转起来&#xff01; 嘿&#xff0c;各位前端小伙伴们&#xff01;今天咱们来聊聊Vue3中的两个新特性&#xff1a;Teleport和Suspense。这两个功能听起来像是从科幻电影里跑出来的&#xff0c;但实际上它们可是能让我们的代码更加优…