[Java 项目亮点] 三层限流设计

思路来源:bilibili 河北王校长


文章目录

    • 面试官可能会问
      • 你能详细介绍一下Nginx的http_limit_req_module模块吗?
      • 你能解释一下如何在Nginx中配置http_limit_req_module模块吗?
      • 你知道如何调整Nginx的http_limit_req_module模块以适应不同的业务需求吗?
      • 什么情况下需要使用burst参数来允许突发的请求数量?
      • 请详细说说 gateway 层面的限流
        • 项目 demo
        • 回答
      • 在网关层面实现限流机制有哪些好处?
      • 为什么用了 `nginx` 还要用 `spring cloud gateway` 呢

image.png

在我们的项目中,我们采用了三层限流设计,以应对高并发场景,同时确保系统的可用性、稳定性,并防止恶意的流量攻击。
首先,第一层限流是在Nginx层面,称为IP限流。我们使用Nginx的http_limit_req_module模块,根据用户IP进行限流。这是第一道防线,主要对抗恶意IP的DDoS攻击,防止大量的非法请求进入到我们系统的深层。
第二层为gateway 对用户层级进行限流。我们根据用户的唯一标识,如user_id,控制每个用户在单位时间内能发送的请求数量。这可以确保公平性,防止单一用户占用过多资源,影响其他用户的使用体验。
第三层为微服务限流。在每个微服务中,我们使用如Google的Guava RateLimiter等技术进行限流。这可以防止某个服务的过载,从而影响整个系统的稳定性。每个服务独立设定限流阈值,根据其自身的处理能力和业务需求调整。
整体来说,这个三层限流的设计,从网络层面到服务层面,层层筛选,有效地把需要处理的请求“漏洞”下来,既保护了系统资源,也保证了高请求量条件下的用户体验和服务的高可用性。

面试官可能会问

你能详细介绍一下Nginx的http_limit_req_module模块吗?

Nginx中的 http_limit_req_module 模块,可以用于限制处理请求的速率,在许多场合非常有用,特别是当您打算保护系统免受任何可能的DDoS攻击时。
这个模块的工作原理是定义一个叫做"速率"的值,这个值是对单位时间内请求的数量进行限制的。比如,你可以设置每分钟只处理100个请求。当某个客户端的请求速率超过这个限制时,Nginx将会把这个请求放入一个队列中,等待处理。如果队列中的请求太多,或者等待的时间太长,那么这个请求就会被丢弃。 在配置文件中,你需要使用limit_req_zone指令来定义这个限制。在这个指令中,你需要指定用于限制速率的关键字,通常情况下,我们会使用客户端的IP地址。然后,你需要设定速率值。 然后,你需要在服务器块或者位置块中,使用limit_req指令来应用这个限制。你也可以通过设置 limit_req 的参数来调整队列的大小或者等待的时间。 通过精心的配置,这个模块可以显著地帮助你提高系统的稳定性和安全性。

你能解释一下如何在Nginx中配置http_limit_req_module模块吗?

使用Nginx的 http_limit_req_module 模块进行限流,需要进行以下步骤配置:
首先,在http块中定义限制速率的区域。这通常使用limit_req_zone指令完成。例如,如果要对IP进行限制,并让每个IP每秒只能有10个请求,可以这样配置:

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

这里$binary_remote_addr是客户端IP,zone=perip:10m定义了一个名为 perip 的存储区,大小为 10M,用于存储每个IP的状态,rate=10r/s则表示限制速率为每秒10个请求。
然后,在需要应用这个限制的server块或location块中,使用limit_req指令来应用这个限制。例如:

server {location /api/ {limit_req zone=perip burst=5;...}
}

这里zone=perip表示应用我们之前定义的perip区域,burst=5表示允许在短时间内超过定义的速率,最多累积5个请求等待处理。
以上便是Nginx的http_limit_req_module模块的基础配置。

你知道如何调整Nginx的http_limit_req_module模块以适应不同的业务需求吗?

Nginxhttp_limit_req_module 模块通过一些配置参数提供了一些调整限流策略的灵活性,以适应不同的业务需求。

  1. rate: 这个参数定义了请求的速率限制,例如rate=10r/s表示每秒钟只允许10个请求。根据业务的需求和服务器的运行能力,你可以灵活调整这个数值。
  2. burst: 这个参数可以允许请求在短时间内超过速率限制,对应的数值即允许突发的请求数量。这个参数可以帮助你在不影响用户体验的前提下进行限流。
  3. nodelay: 通常与burst参数一起使用。如果没有设置nodelay,那么在突发流量到来时,超出rate但在burst范围内的请求会被等待处理,而不是立即处理。如果设置了nodelay,那么超出rate但在burst范围内的请求会立即被处理。

举个例子,假设你的业务主要面向个人用户,且大部分时间请求量稳定,但在某些高峰期会有大量请求,这时候你可能需要设定一个适中的rate,并允许一定量的burst,以提供良好的用户体验。

什么情况下需要使用burst参数来允许突发的请求数量?

在某些情况下,可能会出现短时间内请求突然增多的情况,比如说在某个活动开始的前几秒钟,或者在一个新的服务刚刚上线时。这种突然增多的请求如果超出了之前设置的rate并且没有设置 burst,会被直接丢弃,这可能会导致用户体验下降或者服务可用性降低。 在这种情况下,如果预见到了这样的突然增多的请求,就可以设置 burst 参数来允许一定的突发流量。burst 参数设置的是允许突发请求的数量。这样在短时间内的大量请求就可以被缓冲下来,进入等待队列,而不是被直接丢弃。
例如,如果设置了limit_req zone=mylimit burst=20;,那么在超出rate限制的情况下,还可以允许有20个请求进入等待队列。这样就可以在保证服务稳定性的同时,也不会因为直接丢弃大量请求而影响了用户体验。 所以,当你预见到会有短时间内的突发流量,并且希望这些请求能够得到处理,而不是被直接丢弃,就应该使用 burst 参数来允许一定数量的突发请求。

请详细说说 gateway 层面的限流

项目 demo

如果你是在Spring Cloud Gateway中进行限流的话,你可以使用Spring提供的RequestRateLimiter网关过滤器来实现。
首先,你需要在配置文件中定义你的限流规则。限流规则可以基于不同的key来定义,比如说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}"

在这个例子中,replenishRate定义了每秒可以处理的请求数量,burstCapacity定义了可以接受的突发请求数。key-resolver用于定义如何从请求中获取user_id。
然后,你需要实现一个KeyResolver接口,该接口实现了如何提取user_id。以下的Java代码演示了如何从请求中获取user_id:

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Service
public class UserIdKeyResolver implements KeyResolver {@Overridepublic Mono<String> resolve(ServerWebExchange exchange) {return Mono.just(exchange.getRequest().getQueryParams().getFirst("user_id"));}
}

在这个例子中,user_id从请求的query param中获取。如果user_id在header或者在cookie中,你可能需要修改这部分代码。
这样,Spring Cloud Gateway就会为每个user_id进行限流了。

回答

在我的系统中,我特意设计了一个名为API网关的组件,这就像是系统的入口,所有请求必须通过这个"大门"。为了保证系统在高流量环境下依然稳定运行,我设置了"限流"机制。 在实现限流时,我的做法是首先在网关的配置文件里定义限流规则。我设定了每个用户每秒能发送的请求数量,以及在短时间内允许的最大请求数量。 然后,我需要一种办法来识别每个用户,这就是我提到的"user_id"。通过请求中的一些特定信息,比如查询参数、头信息等,我就可以获取到这个"user_id"。 有了这个设计,我就可以有效地对系统中每个用户的请求进行控制,确保没有任何用户会对系统构成威胁。再者,通过在网关层面实现这个限流机制,我能够为所有应用程序提供统一的限流服务,极大地简化了工作流程和管理。

在网关层面实现限流机制有哪些好处?

实现网关层面的限流机制有很多好处。比如:

  1. 统一管理:通过在网关层级实现限流,我能够在一个集中的地方来管理所有服务的流量控制,而无需在每个服务中单独配置。
  2. 防止系统过载:限流可以防止任何一个服务因为过大的流量而崩溃,这样可以增加系统的稳定性。
  3. 公平性:限流能够确保所有的用户都得到合理的请求量,防止某些用户占用大量的资源。
  4. 服务保护:如果有服务出现问题或者异常,限流机制可以防止这个服务的问题扩散到整个系统,起到了一定的隔离效果。
  5. 方便的应对突发流量:如果我有预期到的高流量请求,我可以快速地在网关层面做出调整来应对。

所以,实现网关层面的限流对于保证系统的稳定性和公平性,以及方便的系统管理都有着重要的作用。

为什么用了 nginx 还要用 spring cloud gateway

当然, 面试官问的问题非常好。在我的项目中,尽管我可以使用Nginx进行负载均衡、反向代理和限流等操作,但我仍选择了Spring Cloud Gateway作为我的微服务的API网关,有以下几个原因。
首先,我的项目主要基于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://xiahunao.cn/news/2806465.html

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

相关文章

Mybatis总结--传参

MyBatis 传递参数&#xff1a;从 java 代码中把参数传递到 mapper.xml 文件 六、一个简单参数&#xff1a; Dao 接口中方法的参数只有一个简单类型&#xff08; java 基本类型和 String &#xff09;&#xff0c; 占位符 #{ 任意字符 } &#xff0c;和方法的参数名无关…

Mac OS 搭建C++开发环境【已解决】

Mac OS 搭建C开发环境 文章目录 Mac OS 搭建C开发环境一、安装命令行工具&#xff1a;二、安装vscode三、安装gcc3.1 安装Homebrew3.2 安装gcc3.3 修改配置 四、更改VSCode默认编译器五、安装gdb六、安装Cmake && git七、编译运行 本地环境&#xff1a; Mac OS Sonoma …

VTK的渲染原理

下面三张图均是用VTK实现的&#xff0c;从中很容易看出它们渲染的效果是有区别的&#xff1a; 第一张图&#xff1a;过于明亮&#xff0c;看不到阴影&#xff0c;颜色过渡也不平缓&#xff1b; 第二张图&#xff1a;阴影过于明显&#xff0c;图整体不够明亮&#xff1b; 第三…

C++基础知识(四:类的学习)

类 类指的就是对同一类对象&#xff0c;把所有的属性都封装起来&#xff0c;你也可以把类看成一个高级版的结构体。 【1】定义 class 类名 { 访问权限:成员属性; 访问权限:成员方法; }访问权限&#xff1a; public:共有的&#xff0c;类内、类外和子类中都可以访问 private:私有…

接近于pi的程序

在一个平静的午后&#xff0c;两个神秘的数字悄然相遇了。它们分别是-1031158223和-328227871。这两个数字看起来普普通通&#xff0c;但谁知它们背后隐藏着一段令人惊叹的奇幻之旅。 这两个数字其实是π的两位探险家&#xff0c;它们决定通过一次除法运算来探索π的奥秘。它们…

怎么在线生成动态gif?这个网站一定要知道

静态图片是指一张固定的、不具有动态效果的图片。它通常是由像素点组成的&#xff0c;可以是照片、插图、图标等。静态图片只能呈现一种特定的场景或图像&#xff0c;不能展示动态变化。动态图片&#xff08;是由一系列静态图片组成的&#xff0c;通过快速连续播放这些画面&…

线程共享和非共享的资源及线程优缺点

注意&#xff1a;共享的内存地址空间中不包括栈&#xff1b;共享文件描述符表&#xff0c;表示&#xff0c;同一进程中线程可以操作同一文件。

使用代理IP技术实现爬虫同步获取和保存

概述 在网络爬虫中&#xff0c;使用代理IP技术可以有效地提高爬取数据的效率和稳定性。本文将介绍如何在爬虫中同步获取和保存数据&#xff0c;并结合代理IP技术&#xff0c;以提高爬取效率。 正文 代理IP技术是一种常用的网络爬虫技术&#xff0c;通过代理服务器转发请求&a…

力扣 48. 旋转图像

1.题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…

探索设计模式的魅力:状态模式揭秘-如何优雅地处理复杂状态转换

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 探索设计模式的魅力&#xff1a;状态模式揭秘-如何优雅地处理复杂状态转换 文章目录 一、案例…

HCIA-HarmonyOS设备开发认证V2.0-IOT硬件子系统-WatchDog

目录 一、 WATCHDOG 概述功能简介基本概念 二、WATCHDOG 模块相关API三、WATCHDOG HDF驱动开发3.1、开发步骤(待续...) 坚持就有收获 一、 WATCHDOG 概述 功能简介 看门狗&#xff08;Watchdog&#xff09;&#xff0c;又称看门狗计时器&#xff08;Watchdog timer&#xff0…

零基础学编程,编程简单学,中文编程工具下载及工具箱进度条构件的用法

一、前言 今天给大家分享的中文编程开发语言工具 进度条构件的用法。 编程入门视频教程链接 https://edu.csdn.net/course/detail/39036 编程工具及实例源码文件下载可以点击最下方官网卡片——软件下载——常用工具下载——编程工具免费版下载及实例源码下载。 进度条 进度…

涵盖5大领域的机器学习工具介绍

随着数据的产生及其使用量的不断增加&#xff0c;对机器学习模型的需求也在成倍增加。由于ML系统包含了算法和丰富的ML库&#xff0c;它有助于分析数据和做出决策。难怪机器学习的知名度越来越高&#xff0c;因为ML应用几乎主导了现代世界的每一个方面。随着企业对这项技术的探…

信息检索(二):Dense Passage Retrieval for Open-Domain Question Answering

Dense Passage Retrieval for Open-Domain Question Answering 摘要1. 引言2. 背景3. DPR4. 实验设置5. 实验&#xff1a;文章检索6. 实验&#xff1a;问题问答7. 相关工作8. 结论参考资料 原文链接&#xff1a;https://aclanthology.org/2020.emnlp-main.550.pdf DPR 最早引入…

六、回归与聚类算法 - K-means算法

目录 1、K-means 聚类步骤 2、API 3、案例 4、性能评估指标 5、总结 线性回归欠拟合与过拟合线性回归的改进 - 岭回归分类算法&#xff1a;逻辑回归模型保存与加载无监督学习&#xff1a;K-means算法 1、K-means 聚类步骤 2、API 3、案例 4、性能评估指标 5、总结

【数据结构与算法初学者指南】【冲击蓝桥篇】String与StringBuilder的区别和用法

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

【 JS 进阶 】Web APIs (一)

“生命是一曲奇妙的交响&#xff0c;每一段都是挑战&#xff0c;每一个音符都是机遇。在激情的旋律中&#xff0c;用勇气弹奏&#xff0c;创造出属于自己的华彩人生。” - 贝多芬 了解 DOM 的结构并掌握其基本的操作&#xff0c;体验 DOM 的在开发中的作用 知道 ECMAScript 与 …

基于SpringBoot的家教管理系统

基于SpringBootVue的家教管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台主页 家教 个人中心 管理员界面 摘要 本文介绍了基于SpringBoot框架开发的家…

【深度学习笔记】3_5 图像分类数据集fashion-mnist

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.5 图像分类数据集&#xff08;Fashion-MNIST&#xff09; 在介绍softmax回归的实现前我们先引入一个多类图像分类数据集。它将在后面的章节中被多次使用&#xff0c…

论文是怎么一回事

最近找到女朋友了&#xff0c;她还挺关心我毕业和论文的事情&#xff0c;我开始着手弄论文了~ 说来惭愧&#xff0c;我一直以为读研就是做东西当作工作来完成&#xff0c;结果一直陷入如何实现的问题&#xff0c;结果要论文时不知道怎么弄创新点&#xff0c;这才转过头来弄论文…