SpringCloudGateway网关限流

文章目录

      • 令牌桶算法原理
      • Gateway中限流实现


在这里插入图片描述

网关除了请求路由、身份验证,还有一个非常重要的作用:请求限流。当系统面对高并发请求时,为了减少对业务处理服务的压力,需要在网关中对请求限流,按照一定的速率放行请求。

常见的限流算法包括:

  • 计数器算法
  • 漏桶算法
  • 令牌桶算法

算法介绍: https://blog.csdn.net/u012441595/article/details/102483501


令牌桶算法原理

SpringGateway中采用的是令牌桶算法,令牌桶算法原理:

  • 准备一个令牌桶,有固定容量,一般为服务并发上限
  • 按照固定速率,生成令牌并存入令牌桶,如果桶中令牌数达到上限,就丢弃令牌。
  • 每次请求调用需要先获取令牌,只有拿到令牌,才继续执行,否则选择选择等待或者直接拒绝。

在这里插入图片描述



Gateway中限流实现

SpringCloudGateway是采用令牌桶算法,其令牌相关信息记录在redis中,因此我们需要安装redis,并引入Redis相关依赖。

1) 引入redis有关依赖:

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

注意:这里不是普通的redis依赖,而是响应式的Redis依赖,因为SpringGateway是基于WebFlux的响应式

2) 配置过滤条件key:

Gateway会在Redis中记录令牌相关信息,我们可以自己定义令牌桶的规则,例如:

  • 给不同的请求URI路径设置不同令牌桶

  • 给不同的登录用户设置不同令牌桶

  • 给不同的请求IP地址设置不同令牌桶

Redis中的一个Key和Value对就是一个令牌桶。因此Key的生成规则就是桶的定义规则。SpringCloudGateway中key的生成规则定义在KeyResolver接口中:

public interface KeyResolver {Mono<String> resolve(ServerWebExchange exchange);}

这个接口中的方法返回值就是给令牌桶生成的key。API说明:

  • Mono:是一个单元素容器,用来存放令牌桶的key
  • ServerWebExchange:上下文对象,可以理解为ServletContext,可以从中获取request、response、cookie等信息

比如上面的三种令牌桶规则,生成key的方式如下:

  • 给不同的请求URI路径设置不同令牌桶,示例代码:

    return Mono.just(exchange.getRequest().getURI().getPath());// 获取请求URI
    
  • 给不同的登录用户设置不同令牌桶

    return exchange.getPrincipal().map(Principal::getName);// 获取用户
    
  • 给不同的请求IP地址设置不同令牌桶

    return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());// 获取请求者IP
    

这里我们选择最后一种,使用IP地址的令牌桶key。

我们定义一个类,配置一个 KeyResolve r的 Bean 实例:

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class PathKeyResolver implements KeyResolver {@Overridepublic Mono<String> resolve(ServerWebExchange exchange) {return Mono.just(exchange.getRequest().getURI().getPath());// 获取请求URI}
}

3) 配置桶参数:

另外,令牌桶的参数需要通过yaml文件来配置,参数有2个

  • replenishRate:每秒钟生成令牌的速率,基本上就是每秒钟允许的最大请求数量

  • burstCapacity:令牌桶的容量,就是令牌桶中存放的最大的令牌的数量

完整配置如下:

server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称redis:host: localhostcloud:nacos:server-addr: localhost:8848 # nacos地址gateway:routes: # 网关路由配置- id: user-server # 路由id,自定义,只要唯一即可# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址uri: lb://user-server# 路由的目标地址 lb就是负载均衡,后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/user/**- id: order-service # 路由id,自定义,只要唯一即可uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称predicates: # 路由断言,也就是判断请求是否符合路由规则的条件- Path=/order/**default-filters:- AddRequestHeader=name,xiaoming- name: RequestRateLimiter #请求数限流 名字不能随便写args:key-resolver: "#{@ipKeyResolver}" # 指定一个key生成器redis-rate-limiter.replenishRate: 2 # 生成令牌的速率redis-rate-limiter.burstCapacity: 4 # 桶的容量globalcors: # 全局的跨域处理........

这里配置了一个过滤器:RequestRateLimiter,并设置了三个参数:

  • key-resolver"#{@ipKeyResolver}"是SpEL表达式,写法是#{@bean的名称},ipKeyResolver就是我们定义的Bean名称
  • redis-rate-limiter.replenishRate:每秒钟生成令牌的速率
  • redis-rate-limiter.burstCapacity:令牌桶的容量

这样的限流配置可以达成的效果:

  • 每一个IP地址,每秒钟最多发起2次请求
  • 每秒钟超过2次请求,则返回429的异常状态码

4) 测试
在这里插入图片描述

429:代表请求次数过多,触发限流了。




在这里插入图片描述



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

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

相关文章

Android Studio如何修改JDK版本和获知使用的Java版本

什么是JDK和Java版本&#xff1f; 首先&#xff0c;让我们简单了解一下什么是JDK和Java版本。JDK&#xff08;Java Development Kit&#xff09;是Java开发工具包的缩写&#xff0c;它包含了Java的运行环境&#xff08;JRE&#xff09;和开发工具&#xff0c;用于开发Java应用…

【数据结构】单链表的层层实现!! !

关注小庄 顿顿解馋(●’◡’●) 上篇回顾 我们上篇学习了本质为数组的数据结构—顺序表&#xff0c;顺序表支持下标随机访问而且高速缓存命中率高&#xff0c;然而可能造成空间的浪费&#xff0c;同时增加数据时多次移动会造成效率低下&#xff0c;那有什么解决之法呢&#xff…

VS Code引入ECharts

Charts是一个使用 JavaScript 实现的开源可视化库&#xff0c;涵盖各行业图表&#xff0c;提供了丰富的图表类型和交互能力。&#xff08;摘自菜鸟教程&#xff09; 下面我们来介绍一下VS Code引入ECharts的相关操作 检查电脑是否已经安装了Java语言的软件开发工具包 ECharts…

设计模式-行为型设计模式-命令模式

命令模式&#xff08;Command&#xff09;&#xff0c;将一个请求封装为一个对象&#xff0c;从而使你可用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志&#xff0c;以及支持可撤销的操作。[DP] // 命令接口 interface Command {void execute(); }// 具体命…

备考银行科技岗刷题笔记(持续更新版)

银行考试计算机部分复习 IEEE 802.11的帧格式 1.1 IEEE 802.11是什么&#xff1f; 802.11是国际电工电子工程学会&#xff08;IEEE&#xff09;为无线局域网络制定的标准。目前在802.11的基础上开发出了802.11a、802.11b、802.11g、802.11n、802.11ac。并且为了保证802.11更…

java SSM售后服务管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

源码特点 java SSM售后服务管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采用B/…

java Lambda表达式如何实现函数递归

java Lambda表达式如何实现函数递归 Lambda表达式本身并不直接支持递归&#xff0c;因为Lambda表达式是匿名的&#xff0c;并且没有名字可以引用自身来实现递归。但是&#xff0c;你可以通过其他方式在Java中使用Lambda表达式来实现递归。 一种常见的做法是使用一个函数式接口…

Scrapy与分布式开发(2.3):lxml+xpath基本指令和提取方法详解

lxmlxpath基本指令和提取方法详解 一、XPath简介 XPath&#xff0c;全称为XML Path Language&#xff0c;是一种在XML文档中查找信息的语言。它允许用户通过简单的路径表达式在XML文档中进行导航。XPath不仅适用于XML&#xff0c;还常用于处理HTML文档。 二、基本指令和提取…

Linux下阻塞IO驱动实验实例一

一. 简介 前面几篇文章学习了 Linux内核提供的 阻塞与非阻塞IO相关的知识。 应用程序以阻塞方式访问设备时,Linux内核提供了等待队列来处理。当应用程序以非阻塞方式访问设备时,Linux内核提供了 poll轮训机制来处理。 前面一篇文章学习了Linux内核提供的非阻塞式访问设备…

Java面试题:Java多线程与并发面试题解析及知识梳理,Java中的线程池(ThreadPool)以及其重要性

随着互联网技术的不断发展&#xff0c;Java作为后端开发的主流语言之一&#xff0c;其并发编程和多线程机制得到了越来越多的关注。面试中&#xff0c;关于Java内存模型、多线程以及并发相关的知识点往往是面试官关注的重点。本文将为大家解析三道综合面试题&#xff0c;涵盖Ja…

自编C++题目——几点了 hard ver.

题目难度 普及- 题目描述 一个老外用一口不流利的中文问你&#xff1a;“Xian zai ji dian le?”你看了一眼表&#xff0c;知道了现在是&#xff0c;你准备用这样的形式写在纸上&#xff1a; Now is m past/to h. 如果你看不懂&#xff0c;举个例子&#xff1a; 当h10&…

Rollup Summer:一览 Rollup 生态全景图

作者&#xff1a;Stanley&#xff0c;Kernel Ventures 编译&#xff1a;JIN&#xff0c;Techub News 短短几天内&#xff0c;ZKFair 的总锁定价值&#xff08;TVL&#xff09;已达到 1.2 亿美元&#xff0c;目前稳定在 8000 万美元&#xff0c;使其成为增长最快的 Rollup 之一…

SHARE 100M PRO:航测领域的多面手

在无人机航测领域&#xff0c;SHARE 100M PRO单镜头航测相机以其1.02亿像素的中画幅传感器和创新技术&#xff0c;正在重塑倾斜摄影的精度和效率。这款相机不仅在城市规划和土地管理中发挥着重要作用&#xff0c;还在环境监测、基础设施建设、农业管理等多个航测领域展现出其卓…

sheng的学习笔记-AI-多分类学习:ECOC,softmax

目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 基本术语&#xff1a; 若我们欲预测的是离散值&#xff0c;例如“好瓜”“坏瓜”&#xff0c;此类学习任务称为“分类”(classification)&#xff1b; 若欲预测的是连续值&#xff0c;例如西瓜成熟度0.95、0.37&#xff0c;…

软考69-上午题-【面向对象技术2-UML】-关系

一、关系 UML中有4种关系&#xff1a; 依赖&#xff1b;关联&#xff1b;泛化&#xff1b;实现。 1-1、依赖 行为&#xff08;参数&#xff09;&#xff0c;参数就是被依赖的事物&#xff0c;即&#xff1a;独立事物。 当独立事物发生变化时&#xff0c;依赖事务行为的语义也…

IDEA中如何:创建Java可执行JAR文件

在IntelliJ IDEA中&#xff0c;你可以通过以下步骤来创建Java可执行JAR文件&#xff1a; 步骤1&#xff1a;编写Java代码 首先&#xff0c;在IntelliJ IDEA中编写你的Java代码。 步骤2&#xff1a;配置项目结构 确保你的项目已经正确配置了项目结构。如果你的项目是一个Mav…

js【详解】原型 vs 原型链

原型 每个 class 都有显示原型 prototype每个实例都有隐式原型_proto_实例的_proto_指向对应 class 的 prototype 如下范例&#xff1a; class Student 创建了 实例 xialuo 获取属性 xialuo.name 或执行方法 xialuo.sayhi()时&#xff0c;先在自身属性和方法寻找&#xff0…

Visual Studio 2022 Version 17.9 新功能

Visual Studio 2022 v17.9 为广大 C 开发者引入了一系列好用的新功能和改进优化。 内存布局 现在&#xff0c;你可以使用【内存布局&#xff0c;Memory Layout】功能以可视化的方式来查看对象&#xff0c;结构体及联合体的内存布局信息&#xff0c;这可比以前需要手动查看内存…

IOS面试题object-c 31-40

31、 Object-C对象如何进行内存布局&#xff1f;1&#xff0c;所有父类的成员变量和自己的成员变量&#xff08;实例变量、私有变量、以及声明为属性生成的变量&#xff09;都会存放在该对象所对应的存储空间中。 2&#xff0c;每个对象内部都有一个 isa 指针&#xff0c;指向他…

变量的生命周期详解

变量的生命周期详解 文章目录 变量的生命周期详解前言一、局部变量&#xff08;Local Variables&#xff09;二、成员变量&#xff08;Member Variables&#xff09;或实例变量&#xff08;Instance Variables&#xff09;三、静态变量&#xff08;Static Variables&#xff09…