三层限流:为高并发系统保驾护航

文章目录

  • 前言
  • 第一层限流:Nginx 层面的 IP 限流
  • 第二层限流:Gateway 对用户层级的限流
  • 第三层限流:微服务限流
    • 分布式限流和单机限流的优缺点:
    • 1、RateLimiter的使用
    • 2、Hystrix的使用
    • 3、Redis+lua脚本
    • 4、使用Sentinel
  • 关于为何同时使用 Nginx 和 Spring Cloud Gateway

前言

在高并发网络环境中,确保系统的可用性、稳定性以及防范恶意流量攻击至关重要。为此,在我们的项目中构建了三层限流设计。

第一层是 Nginx 层面的 IP 限流,借助 Nginx 的 http_limit_req_module 模块,依据用户 IP 设限,这是抵御恶意 IP 的 DDoS 攻击、阻挡大量非法请求深入系统的首道防线。

第二层为 gateway 针对用户层级的限流,通过用户的唯一标识如 user_id,控制每个用户在单位时间内的请求数量,确保公平,避免单一用户过度占用资源而影响他人体验。

第三层则是微服务限流,每个微服务运用如 Google 的 Guava RateLimiter 等技术限流,防止服务过载影响系统稳定,且各服务根据自身能力和业务需求独立设定限流阈值。

三层限流的结构图如下:
三层流程结构

第一层限流:Nginx 层面的 IP 限流

Nginx 的 http_limit_req_module 模块是我们构建的第一道坚固防线。 其工作原理基于定义一个明确的“速率”值,用于对单位时间内的请求数量进行严格的限制。比如说,您可以设定每分钟只处理 100 个请求。当某个客户端的请求速率超过预先设定的限制时,Nginx 就会地将这些请求放入一个专门的队列中,等待后续的处理。然而,如果队列中的请求数量过多,或者等待处理的时间超出了可接受的范围,那么这些请求将会被果断丢弃。

在配置方面,首先需要在 Nginx 的 http 块中使用 limit_req_zone 指令来定义限制速率的区域。例如,如果我们决定根据客户端的 IP 进行限制,限流20MB,每秒允许处理1000个请求,配置如下:

http http {   limit_req_zone $binary_remote_addr zone=perip:20m rate=1000r/s; ...
} 

这里,$binary_remote_addr 代表客户端的 IP 地址,zone=totalLimit:20m 定义了一个名为 totalLimit 的存储区域,其大小为 20M,用于存储每个 IP 的状态信息,而 rate=10r/s 则清晰地设定了每秒 1000 个请求的限制速率。

接下来,在需要应用这个限制的 server 块或 location 块中,使用 limit_req 指令来设定这个限制。例如:

json server {    location / {        limit_req zone=totalLimit burst=1000 nodelay;...}
}

​ 在上述配置中,zone=totalLimit 明确表示应用之前定义的 totalLimit 区域,而 burst=1000 则意味着允许在短时间内超过定义的速率,最多累积 1000 个请求等待处理。 通过调整 rateburstnodelay 等配置参数,我们能够根据不同的业务需求灵活定制限流策略。比如,假设我们的业务主要面向个人用户,并且大部分时间请求量相对稳定,但在某些特定的高峰期会出现请求量的突然增加。在这种情况下,我们可能会选择设定一个适中的 rate ,并同时允许一定数量的 burst ,以在保障系统稳定性的同时,最大程度地优化用户体验。

第二层限流:Gateway 对用户层级的限流

为了进一步增强系统的限流效果和精细化管理,我们在 API 网关层面也实施了限流策略。 首先,在 Spring Cloud Gateway 中,通过在配置文件中明确地定义限流规则,我们能够基于 user_id 这一关键标识,精准地控制每个用户在单位时间内所能发送的请求数量。以下是一个针对 user_id 进行限流的配置示例:

spring:cloud:gateway:routes:- id: user_routeuri: http://mybackend.compredicates:- Path=/api/**filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20key-resolver: "#{@userIdResolver}"

在这个配置中,redis-rate-limiter.replenishRate 定义了每秒可以处理的请求数量,而 redis-rate-limiter.burstCapacity 则设定了可以接受的突发请求数量。同时,key-resolver 用于明确如何从请求中准确获取 user_id

为了实现从请求中提取 user_id ,我们需要实现一个 KeyResolver 接口。以下是一个使用 Java 语言实现的示例代码,展示了如何从请求的查询参数中获取 user_id

1、引入依赖

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

2、配置获取用户id的方法

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Configuration
public class RateLimiterConfiguration@BeanKeyResolver userIdKeyResolver(){return Mono.just(exchange.getRequest().getQueryParams().getFirst("user_id"));}
}

3、配置c配置文件中的过滤配置

spring:cloud:gateway:filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 1000     # 令牌桶每秒填充平均速率redis-rate-limiter.burstCapacity: 2000     # 令牌桶的上限key-resolver: "#{@userIdResolver}"        # 使用spel表达式从spring容器中获取Bean对象

网关层面限流的好处众多,通过这样的设计,极大地简化了整个系统的工作流程和管理复杂度。 网关层面实现限流机制带来了诸多显著的好处。

首先,它能够为所有的应用程序提供一个统一的流量控制管理,使得我们能够在一个集中的位置对所有服务的流量进行有效的监管和控制,而无需在每个服务中分别进行复杂的配置。

其次,限流机制能够有效地防止任何一个服务由于过大的流量冲击而陷入崩溃的境地,从而显著增强了系统的稳定性。

再者,它能够有效地对系统中的每个用户的请求进行精确控制,避免了某些用户过度占用系统资源而对其他用户的体验造成不良影响。

最后,对于可预期的高流量请求场景,我们能够在网关层面迅速而灵活地进行调整和应对,保障系统的正常运行。

第三层限流:微服务限流

在每个微服务内部,每个微服务都能够根据自身的处理能力和独特的业务需求,独立设定限流阈值。这种个性化的设置确保了每个微服务在面对不同的负载情况时,都能够保持稳定的性能和可靠的服务质量,从而有效地防止了某个服务的过载对整个系统的稳定性产生不利影响。

在这层中有多种技术来实现微服务限流,可以采用,如 Google 的 Guava RateLimiter、SpringCloud的Hystrix等框架来实施单机限流策略,也可以采用 阿里的Sentinel、或者自己用Redis+lua脚本实现分布式限流对微服务多个实例统一限流。

分布式限流和单机限流的优缺点:

分布式限流的优点:

  1. 全局一致:确保整个系统限流策略统一,维持稳定。
  2. 适应高并发:处理大规模、高流量场景,保障系统稳定。
  3. 弹性扩展:随系统规模变化能灵活调整限流策略。
  4. 精准控制:依据系统整体情况精确限流。

**分布式限流的缺点: **

  1. 复杂:实现和维护难度大,涉及协调和同步问题。

  2. 有性能开销:节点通信带来一定性能损失。

  3. 依赖外部组件:增加系统依赖和故障点。

单机限流的优点:

  1. 简单:实现逻辑简单,无需复杂协调机制。

  2. 低开销:无节点通信,性能影响小。

  3. 独立:限流策略不受其他节点干扰。

单机限流的缺点:

  1. 局限:只能处理单机器流量。
  2. 缺乏协调:不同机器策略难统一,影响系统稳定。
  3. 难扩展:无法直接用于多机环境。

1、RateLimiter的使用

RateLimiter使用起来比较简单,代码示例如下

 public static void main(String[] args) {// 创建一个每秒放入5个令牌的RateLimiterRateLimiter limiter = RateLimiter.create(100.0);for (int i = 0; i < 10; i++) {// 请求一个令牌limiter.acquire();System.out.println("处理请求: " + i);}}

这段代码创建了一个RateLimiter,它每秒产生100个令牌。在一个循环中,我们通过acquire()方法从RateLimiter获取令牌。如果令牌不够,acquire()会阻塞,直到获取到令牌

2、Hystrix的使用

Hystrix的限流是基于线程池的所以在配置文件里设置hystrix线程池的核心线程数就可实现限流

hystrix:threadpool:default:coreSize: 200 #并发执行的最大线程数,默认10maxQueueSize: 1000 #BlockingQueue的最大队列数,默认值-1queueSizeRejectionThreshold: 800 #即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5

3、Redis+lua脚本

limit.lua

local count
- 获取调用脚本时传入的第一个key值(用作限流的 key)
count = redis.call('get',KEYS[1])
-- 获取调用脚本时传入的第一个参数值(限流大小)
if count and tonumber(count) > tonumber(ARGV[1]) thenreturn count;
endcount = redis.call('incr',KEYS[1])
if tonumber(count) == 1 then--从第一次调用开始限流,设置对应key的过期时间redis.call('expire',KEYS[1],ARGV[2])
end
return count;

大致的代码逻辑,实际使用建议封装成一个注解来使用

	DefaultRedisScript<Number> redisScript = new DefaultRedisScript<>();redisScript.setResultType(Number.class);ClassPathResource classPathResource = new ClassPathResource(LIMIT_LUA_PATH);try {classPathResource.getInputStream();//探测资源是否存在redisScript.setScriptSource(new ResourceScriptSource(classPathResource));} catch (IOException e) {logger.error("未找到文件:{}", LIMIT_LUA_PATH);}	List result = stringRedisTemplate.execute(redisScript, keyList, 					String.valueOf(value),String.valueOf(time));Object result = stringRedisTemplate.execute(redisScript, keys, limitCount, limitPeriod);if (result == null) {//降级} Integer count = Integer.valueOf(result.toString());if (count <= limitCount) {//执行业务逻辑} else {//降级}

4、使用Sentinel

Sentinel 是阿里出品的一个功能强大的分布式限流框架,具体使用可以参考下面的官方文档

quick-start | Sentinel (sentinelguard.io)

关于为何同时使用 Nginx 和 Spring Cloud Gateway

首先,我们的项目主要基于 Spring Boot 和 Spring Cloud 进行开发,而 Spring Cloud Gateway 能够与这些技术实现无缝的集成。这种紧密的集成特性不仅减少了我们在处理不同组件之间兼容性问题上所花费的时间和精力,还极大地提高了开发和维护的效率。

其次,Spring Cloud Gateway 支持非阻塞的方式来处理请求,这一特性在处理高并发请求时表现出了显著的优势,是 Nginx 所无法提供的。非阻塞的处理方式能够更高效地利用系统资源,提升系统的整体性能和响应速度。

再者,Spring Cloud Gateway 允许我们通过动态的编程方式来定义路由规则,与 Nginx 相对静态的配置方式形成了鲜明的对比。这种动态定义路由规则的能力使我们能够更加灵活地应对复杂多变的业务需求和系统架构调整,为系统的持续演进提供了有力的支持。

最后,Spring Cloud Gateway 还集成了 Spring Cloud 的服务发现功能,以及与 Spring Cloud 集群紧密配合的断路、降级和限流等机制。这些集成的功能共同强化了微服务架构的健壮性和可靠性,确保系统在面对各种异常情况和高负载场景时,依然能够保持稳定的运行状态,为用户提供持续、优质的服务。

综上所述,虽然 Nginx 已经在网络服务领域展现出了强大的实力,但在我们特定的项目架构中,Spring Cloud Gateway 凭借其与现有技术栈的高度适配性、独特的功能特性以及对微服务架构的全面支持,更加符合我们的项目需求。

综上所述,这三层限流设计相互协作、相辅相成,从不同的层面和角度全方位地保障了系统在高并发场景下的稳定运行。

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

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

相关文章

做PFMEA的经验之谈

在制造业的广袤领域中&#xff0c;PFMEA&#xff08;过程失效模式与影响分析&#xff09;是一项至关重要的工具&#xff0c;它用于识别并评估生产过程中的潜在失效模式&#xff0c;以及这些失效模式可能导致的后果。作为一名在制造业有多年经验的专业机构&#xff0c;深圳天行健…

安装KB5039212更新卡在25% 或者 96% 进度

系统之家7月1日消息&#xff0c;微软在6月11日的补丁星期二活动中&#xff0c;为Windows 11系统推出了KB5039212更新。然而&#xff0c;部分用户在Windows社区中反映&#xff0c;安装过程中出现失败&#xff0c;进度条在25%或96%时卡住。对于遇到此类问题的Windows 11用户&…

【论文复现|智能算法改进】基于自适应动态鲸鱼优化算法的路径规划研究

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 SCI二区|鲸鱼优化算法&#xff08;WOA&#xff09;原理及实现【附完整Matlab代码】 2.改进点 非线性收敛因子 WOA 主要通过控制系数向量 A 来决定鲸鱼是搜索猎物还是捕获猎物&#xff0c;即系数向量 A 可…

【LLM 论文】Self-Refine:使用 feedback 迭代修正 LLM 的 output

论文&#xff1a;Self-Refine: Iterative Refinement with Self-Feedback ⭐⭐⭐⭐ CMU, NeurIPS 2023, arXiv:2303.17651 Code: https://selfrefine.info/ 论文速读 本文提出了 Self-Refine 的 prompt 策略&#xff0c;可以在无需额外训练的情况下&#xff0c;在下游任务上产…

蒂升电梯职业性格和Verify认知能力SHL测评答题攻略及薪资待遇解密!

​一、蒂升电梯职业性格和认知能力测评考什么 您好&#xff01;蒂升电梯公司邀请您参加的OPQ职业性格测评和Verify认知能力测评是两种常见的评估工具&#xff0c;用于帮助了解个人的职场性格特点和认知能力。 OPQ职业性格测评 这是一种性格测试&#xff0c;通常用于评估个人在…

PostgreSQL介绍与安装

一、PostgreSQL数据库介绍 1、什么是数据库&#xff1f; 数据库&#xff08;Database&#xff09;是按照数据结构来组织、存储和管理数据的仓库。每个数据库都有一个或多个不同的 API 用于创建&#xff0c;访问&#xff0c;管理&#xff0c;搜索和复制所保存的数据。 我们也…

倒装COB显示屏与传统SMD显示屏安装方式有哪些不同?

COB显示屏与传统SMD显示屏是商业显示领域中非常重要的两种载体&#xff0c;在前面的文章当中我们为大家阐述了倒装COB显示屏的技术特点&#xff0c;今天跟随COB显示屏厂家深圳市中品瑞科技一起来看看&#xff0c;COB显示屏的安装与传统LED显示屏的安装有哪些不同&#xff1f; 一…

数据结构之“刷链表题”

&#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;数据结构 目录 前言 一、相交链表 题目链接 大致思路 代码实现 二、环形链表1 题目链接 大致思路 代码实现 三、环形链表2 题目链接 大致思路 代码实…

爬虫逆向实战(41)-某巢登陆(AES、MD5、RSA、滑块验证码)

一、数据接口分析 主页地址&#xff1a;某巢 1、抓包 通过抓包可以发现在登录时&#xff0c;网站首先请求captcha/querySlideImage/来获取滑块验证码的图片&#xff0c;然后请求captcha/checkCode/接口来验证滑块验证码。滑块验证码校验成功后&#xff0c;请求noshiro/getPu…

论坛万能粘贴手(可将任意文件转为文本)

该软件可将任意文件转为文本。 还原为原文件的方法&#xff1a;将得到的文本粘贴到记事本&#xff0c;另存为UUE格式&#xff0c;再用压缩软件如winrar解压即可得到原文件。建议用于小软件。 下载地址&#xff1a;https://download.csdn.net/download/wgxds/89505015 使用演示…

Kafka 位移

Consumer位移管理机制 将Consumer的位移数据作为一条条普通的Kafka消息&#xff0c;提交到__consumer_offsets中。可以这么说&#xff0c;__consumer_offsets的主要作用是保存Kafka消费者的位移信息。使用Kafka主题来保存位移。 消息格式 位移主题就是普通的Kafka主题。也是…

HCIE实验这样玩太高级了吧?实现FRR+BFD+OSPF与BGP的联动

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 晚上好&#xff0c;我的网工朋友。 今天搞个HCIE实验玩玩&#xff0c;上回分享了个张总讲解的防火墙配置实验思路&#xff0c;后来还特地搞了个视…

GPT-4o文科成绩超一本线,理科为何表现不佳?

目录 01 评测榜单 02 实际效果 什么&#xff1f;许多大模型的文科成绩竟然超过了一本线&#xff0c;还是在竞争激烈的河南省&#xff1f; 没错&#xff0c;最近有一项大模型“高考大摸底”评测引起了广泛关注。 河南高考文科今年的一本线是521分&#xff0c;根据这项评测&…

【TB作品】打地鼠游戏,ATMEGA16单片机,Proteus仿真 打地鼠游戏

11个按键LCD1602显示器9个灯蜂鸣器打地鼠小游戏就是九个灯泡&#xff0c;对应九个按键&#xff0c;灯泡有红黄蓝&#xff0c;每间隔一会儿就会亮一个灯&#xff0c;代表地鼠冒出来&#xff0c;按一下按键让灯泡灭掉代表打地鼠&#xff0c;红的三分&#xff0c;黄的两分&#xf…

一句话介绍什么是AI智能体?

什么是AI智能体&#xff1f; 一句话说就是利用各种AI的功能的api组合&#xff0c;完成你想要的结果。 例如你希望完成一个关于主题为啤酒主题的小红书文案图片&#xff0c;那么它就可以完成 前面几个步骤类似automa的组件&#xff0c;最后生成一个结果。

IT专业入门——高考假期预习指南,我来做你的引路人

目录 认识IT知识体系 什么是计算机 按规模、速度和功能分类 按照其工作模式分类 硬件 操作系统 编程语言 对学习语言的一点建议 对于学python的一点看法 网络 数据结构与算法 数据库 Web开发 Web前端 Web后端 基础预习指南 技术路线学习一览 学习资源推荐 刷…

开放式耳机哪个品牌最好?2024精选5款热门品牌,新手必看的开放式耳机指南!

最近想买开放式耳机&#xff0c;但面对众多品牌和型号&#xff0c;真的太难挑选了&#xff1f;别担心&#xff0c;作为耳机发烧友和测评专家&#xff0c;我为大家带来了几款热门开放式耳机的横向对比。从6个方面告诉大家怎么样去挑选开放式耳机&#xff0c;并且推荐了几款我觉得…

深度学习 --- stanford cs231学习笔记八(训练神经网络之dropout)

6&#xff0c;dropout 6&#xff0c;1 线性分类器中的正则化 在线性分类器中&#xff0c;我们提到过正则化&#xff0c;其目的就是为了防止过度拟合。例如&#xff0c;当我们要用一条curve去拟合一些散点的数据时&#xff0c;常常是不希望训练出来的curve过所有的点&#xff0c…

<电力行业> - 《第1课:电力行业的五大四小》

1 什么是电力行业的五大四小&#xff1f; 我们常说的电力行业的五大四小&#xff0c;指的是电力行业有实力的公司&#xff0c;分为&#xff1a;较强梯队的五大集团、较弱梯队的四小豪门。 五个实力雄厚的集团&#xff0c;分别是&#xff1a; 中国华能集团公司中国大唐集团公…

文件操作~

目录 1.为什么使用文件&#xff1f; 2.什么是文件&#xff1f; 2.1 程序文件 2.2 数据文件 2.3 文件名 3.⼆进制文件和文本文件&#xff1f; 4.文件的打开和关闭 4.1 流和标准流 4.1.1 流 4.1.2 标准流 4.2 文件指针 4.3 ⽂件的打开和关闭 5.文件的顺序读写 5.1 …