当前位置: 首页 > article >正文

【Java-EE进阶】SpringBoot针对某个IP限流问题

目录

简介

1. 使用Guava的RateLimiter实现限流

添加Guava依赖

实现RateLimiter限流逻辑

限流管理类

控制器中应用限流逻辑

2. 使用计数器实现限流

限流管理类

控制器中应用限流逻辑


简介

针对某个IP进行限流以防止恶意点击是一种常见的反爬虫和防止DoS的措施。限流策略通过对某个IP的访问频率进行控制,防止恶意用户对应用造成负面的影响。

以下是实现限流的步骤和方法,在Java后端通常这样实现:

1. 使用Guava的RateLimiter实现限流

Guava库提供了一个简单而高效的限流工具:RateLimiter,可以方便的实现针对IP的访问频率控制。

添加Guava依赖

首先,在pom.xml文件中添加Guava依赖:

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.1-jre</version>
</dependency>
实现RateLimiter限流逻辑
限流管理类

创建一个类来管理针对IP的限流:

import com.google.common.util.concurrent.RateLimiter;import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;public class RateLimiterManager {private final ConcurrentMap<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<>();private final double permitsPerSecond = 1.0; // 每秒允许1次请求public boolean tryAcquire(String ip) {RateLimiter rateLimiter = rateLimiterMap.computeIfAbsent(ip, k -> RateLimiter.create(permitsPerSecond));return rateLimiter.tryAcquire();}
}
控制器中应用限流逻辑

在Spring Boot控制器中应用限流逻辑:

import com.xfusion.rate1.limit.RateLimiterManager;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;@RestController
@RequestMapping("/test")
public class TestController {private final RateLimiterManager rateLimiterManager=new RateLimiterManager();@RequestMapping("/t1")public void test1(HttpServletRequest request, HttpServletResponse response) throws IOException {String param=request.getRemoteAddr();if(rateLimiterManager.tryAcquire(param)) {response.getWriter().write("Request processed for " + param);} else {response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.getWriter().write("Request limit for " + param);}}
}
private final ConcurrentMap<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<>();
  • ConcurrentMap<String, RateLimiter>

    • 使用ConcurrentMap来存储每个IP的限流器(RateLimiter)。
    • ConcurrentMap接口允许高效地进行并发访问和更新,确保线程安全。
  • new ConcurrentHashMap<>()

    • 实例化一个ConcurrentHashMap,它是ConcurrentMap的常用实现。这种数据结构支持线程安全的读写操作,适合限流场景。
private final double permitsPerSecond = 1.0; // 每秒允许1次请求
  • permitsPerSecond
    • 定义一个double类型的常量permitsPerSecond,值为1.0
    • 表示每秒允许1次请求的限流速率。RateLimiter根据此值来创建相应的限流器。
RateLimiter rateLimiter = rateLimiterMap.computeIfAbsent(ip, k -> RateLimiter.create(permitsPerSecond));
  • computeIfAbsent

    • computeIfAbsent方法用于检查map中是否已经存在为该IP准备的RateLimiter
    • 若不存在,则使用k -> RateLimiter.create(permitsPerSecond)创建一个新的RateLimiter。这个lambda部分表示为未存在的IP创建一个新的RateLimiter,限流速率为permitsPerSecond
  • RateLimiter.create(permitsPerSecond)

    • 调用RateLimiter类的静态方法create,以指定速率创建一个新的限流器实例。这使得每秒最多处理一个请求。
return rateLimiter.tryAcquire();
  • rateLimiter.tryAcquire()
    • 尝试获取一个请求许可。在给定的限流速率范围内,如果成功获取许可,则返回true,否则返回false
    • tryAcquire使得在请求达到速率限制时,予以限制,而不使请求排队。
response.setStatus(HttpServletResponse.SC_FORBIDDEN);

如果我们发现请求达到了上限的时候,设置相应的状态码,然后前端会根据相应的状态码来完成请求,同时就防止这个ip然后再进行访问。

2. 使用计数器实现限流

计数器限流比较简单,通过记录每个IP的请求次数并在指定时间窗口内进行限流。

限流管理类

创建一个类来管理限流逻辑:

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@Configuration
@Component
public class CounterRateLimiter {private final ConcurrentHashMap<String, AtomicInteger> requestCounts = new ConcurrentHashMap<>();private final int maxRequestsPerMinute = 10;public boolean tryAcquire(String ipAddress) {AtomicInteger requestCount = requestCounts.computeIfAbsent(ipAddress, k -> new AtomicInteger(0));int currentCount = requestCount.incrementAndGet();log.info("IP: " + ipAddress + ", Current Count: " + currentCount);return currentCount <= maxRequestsPerMinute;}public void resetCounts() {log.info("Reset counts");requestCounts.clear();}@Scheduled(fixedRate = 10000)public void resetCountsScheduled() {log.info("刷新这个ip的次数");resetCounts();}
}

在开启定时任务的时候,要在Application上添加上@EnableScheduling这个注解

@SpringBootApplication
@Configuration
@EnableScheduling
public class Rate1Application {public static void main(String[] args) {SpringApplication.run(Rate1Application.class, args);}}
控制器中应用限流逻辑

在Spring Boot控制器中应用限流逻辑,并定期重置计数器:

private final CounterRateLimiter counterRateLimiter;public TestController(CounterRateLimiter counterRateLimiter) {this.counterRateLimiter = counterRateLimiter;}@RequestMapping("/t2")public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {String param = request.getRequestURI();if (counterRateLimiter.tryAcquire(param)) {log.info("打印日志1");response.getWriter().write("Request processed for test2 " + param);} else {log.info("打印日志2");response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.getWriter().write("Request limit for test2" + param);}}
@Scheduled(fixedRate = 10000)
public void resetCountsScheduled() {log.info("刷新这个ip的次数");resetCounts();
}
  • @Scheduled(fixedRate = 10000):注解用于配置定时任务,每10秒执行一次。
    • fixedRate:设定定时任务的执行频率,这里设置为每10000毫秒(即每10秒)。
  • resetCountsScheduled 方法:定时任务调用 resetCounts 方法清空计数器。
    • 日志记录:记录定时任务执行。
    • 调用 resetCounts:每10秒自动调用 resetCounts 方法重置计数器。
public void resetCounts() {log.info("Reset counts");requestCounts.clear();
}

resetCounts:用于重置计数器。

  • 日志记录:记录重置计数器操作。
  • clear:清空 requestCounts 中的所有键值对,重置所有IP的计数器

相关文章:

【Java-EE进阶】SpringBoot针对某个IP限流问题

目录 简介 1. 使用Guava的RateLimiter实现限流 添加Guava依赖 实现RateLimiter限流逻辑 限流管理类 控制器中应用限流逻辑 2. 使用计数器实现限流 限流管理类 控制器中应用限流逻辑 简介 针对某个IP进行限流以防止恶意点击是一种常见的反爬虫和防止DoS的措施。限流策…...

一个指令,让任意 AI 快速生成思维导图

大家好&#xff0c;我是安仔&#xff0c;一个每天都在压榨 AI 的躺平打工人。 今天分享一个 AI 办公小技巧&#xff0c;让你用一个指令让 AI 生成思维导图。 DeepSeek、Kimi、豆包都可以哈 &#xff5e; KimiXMind 安仔经常用 XMind 来绘制思维导图&#xff0c;但是 AI 是没…...

随言随语(十二):盖章

给自己的机器学习生涯做个总结盖个章&#xff0c;讲述下如何跟机器学习擦肩而过的&#xff0c;鉴于当前深度学习和大模型已经走出来的路及理论知识的入门难度&#xff0c;可能以后跟机器学习前沿科技就再没有交集了&#xff1b; 最近也看了马占凯的《ChatGPT&#xff1a;人类新…...

FPGA图像处理(六)------ 图像腐蚀and图像膨胀

默认迭代次数为1&#xff0c;只进行一次腐蚀、膨胀 一、图像腐蚀 1.相关定义 2.图像腐蚀效果图 3.fpga实现 彩色图像灰度化&#xff0c;灰度图像二值化&#xff0c;图像缓存生成滤波模块&#xff08;3*3&#xff09;&#xff0c;图像腐蚀算法 timescale 1ns / 1ps // // Des…...

Spring三级缓存的作用与原理详解

在Spring框架中&#xff0c;Bean的创建过程涉及到了三级缓存机制。这个机制主要是为了提高单例模式下bean实例化和依赖注入的效率。本文将深入探讨Spring中的三级缓存&#xff0c;以及其在bean生命周期中的重要作用。 首先&#xff0c;让我们理解什么是三级缓存。Spring中的三…...

LVDS系列12:Xilinx Ultrascale系可编程输入延迟(二)

本节讲解Ultrascale IDELAYE3的参数&#xff1b;  IDELAYE3参数&#xff1a; REFCLK_FREQUENCY&#xff1a;如果使用COUNT模式&#xff0c;保持300MHz的默认值即可&#xff1b; 如果使用TIME模式&#xff0c;则该值与IDELAYCTRL参考时钟要匹配&#xff1b; DELAY_SRC&#…...

ARM (Attention Refinement Module)

ARM模块【来源于BiSeNet】&#xff1a;细化特征图的注意力&#xff0c;增强重要特征并抑制不重要的特征。 Attention Refinement Module (ARM) 详解 ARM (Attention Refinement Module) 是 BiSeNet 中用于增强特征表示的关键模块&#xff0c;它通过注意力机制来细化特征图&…...

国产免费工作流引擎star 6.5k,Warm-Flow升级1.7.2(新增案例和修复缺陷)

文章目录 主要更新内容项目介绍功能思维导图设计器流程图演示地址官网Warm-Flow视频 主要更新内容 [feat] 开启流程实例&#xff0c;新增流程定义是否存在校验[feat] 新增合同签订流程案例[feat] 新增企业采购流程案例[update] mybatis-plus逻辑删除&#xff0c;删除值和未删除…...

前端二进制数据指南:从 ArrayBuffer 到高级流处理

前端开发中&#xff0c;二进制数据是处理文件、图像、音视频、网络通信等场景的基础。以下是核心概念和用途的通俗解释&#xff1a; 前端二进制数据介绍 1. 什么是前端二进制数据&#xff1f; 指计算机原始的 0 和 1 格式的数据&#xff08;比如一张图片的底层代码&#xff…...

如何选择高性价比的 1T 服务器租用服务​

选择高性价比的 1T 服务器租用服务​&#xff0c;可参考以下内容&#xff1a; 1、根据需求选配置​ 明确自身业务需求是关键。若为小型网站或轻量级应用&#xff0c;数据存储与处理需求不高&#xff0c;选择基础配置服务器即可。如个人博客网站&#xff0c;普通的 Intel Xeon …...

一个可拖拉实现列表排序的WPF开源控件

从零学习构建一个完整的系统 推荐一个可通过拖拉&#xff0c;来实现列表元素的排序的WPF控件。 项目简介 gong-wpf-dragdrop是一个开源的.NET项目&#xff0c;用于在WPF应用程序中实现拖放功能&#xff0c;可以让开发人员快速、简单的实现拖放的操作功能。 可以在同一控件内…...

AI-02a5a6.神经网络-与学习相关的技巧-批量归一化

批量归一化 Batch Normalization 设置合适的权重初始值&#xff0c;则各层的激活值分布会有适当的广度&#xff0c;从而可以顺利的进行学习。那么&#xff0c;更进一步&#xff0c;强制性的调整激活值的分布&#xff0c;是的各层拥有适当的广度呢&#xff1f;批量归一化&#…...

SVGPlay:一次 CodeBuddy 主动构建的动画工具之旅

我正在参加CodeBuddy「首席试玩官」内容创作大赛&#xff0c;本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 背景与想法 我一直对 SVG 图标的动画处理有浓厚兴趣&#xff0c;特别是描边、渐变、交互等效果能为图标增添许…...

自己手写tomcat项目

一&#xff1a;Servlet的原理 在Servlet(接口中)有&#xff1a; 1.init():初始化servlet 2.getServletConfig()&#xff1a;获取当前servlet的配置信息 3.service():服务器&#xff08;在HttpServlet中实现&#xff0c;目的是为了更好的匹配http的请求方式&#xff09; 4.g…...

2025年渗透测试面试题总结-安恒[实习]安全工程师(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 安恒[实习]安全工程师 一面 1. 自我介绍 2. 前两段实习做了些什么 3. 中等难度的算法题 4. Java的C…...

生成对抗网络(Generative Adversarial Networks ,GAN)

生成对抗网络是深度学习领域最具革命性的生成模型之一。 一 GAN框架 1.1组成 构造生成器&#xff08;G&#xff09;与判别器&#xff08;D&#xff09;进行动态对抗&#xff0c;实现数据的无监督生成。 G&#xff08;造假者&#xff09;&#xff1a;接收噪声 ​&#xff0c…...

六、磁盘划分与磁盘配额

目录 1、磁盘划分1.1、什么是磁盘1.2、机械硬盘的结构与关键概念1.3、思考:为什么新买一个1T硬盘,使用时发现可使用容量低于1T1.4、Linux中inode和block1.5、查看超级快信息1.6、磁盘分区与挂载1.6.1、分区工具fdisk与格式化1.6.2、分区工具gdisk与格式化1.7、查看磁盘使用情…...

在WSL中的Ubuntu发行版上安装Anaconda、CUDA、CUDNN和TensorRT

在Windows 11的WSL&#xff08;Windows Subsystem for Linux&#xff09;环境中安装Anaconda、CUDA、CUDNN和TensorRT的详细步骤整理&#xff1a; 本文是用cuda12.4与CuDNN 8.9.7 和 TensorRT 9.1.0 及以上对应 一、前言&#xff08;准备&#xff09; 确保电脑上有NVIDIA GPU…...

小刚说C语言刷题—1230蝴蝶结

1.题目描述 请输出 n 行的蝴蝶结的形状&#xff0c;n 一定是一个奇数&#xff01; 输入 一个整数 n &#xff0c;代表图形的行数&#xff01; 输出 n 行的图形。 样例 输入 9 输出 ***** **** *** ** * ** *** **** ***** 2.参考代码&#xff08;C语言版&#xff09…...

代码随想录算法训练营第60期第三十九天打卡

大家好&#xff0c;我们今天继续讲解我们的动态规划章节&#xff0c;昨天我们讲到了动态规划章节的背包问题&#xff0c;昨天讲解的主要是0-1背包问题&#xff0c;那么今天我们可能就会涉及到完全背包问题&#xff0c;昨天的题目有一道叫做分割等和子集&#xff0c;今天应该会有…...

计算机网络体系结构深度解析:从理论到实践的全面梳理

计算机网络体系结构深度解析&#xff1a;从理论到实践的全面梳理 本系列博客源自作者在大二期末复习计算机网络时所记录笔记&#xff0c;看的视频资料是B站湖科大教书匠的计算机网络微课堂&#xff0c;祝愿大家期末都能考一个好成绩&#xff01; 一、常见计算机网络体系结构 …...

Qwen2.5-VL模型sft微调和使用vllm部署

本文的server.py和req.py代码参见&#xff1a;https://github.com/zysNLP/quickllm 配套课程《AIGC大模型理论与工业落地实战》&#xff1b;Deepseek相关课程更新中 1. 安装相关docker镜像&#xff1a;nvcr.io/nvidia/pytorch:25.02-py3 docker pull nvcr.io/nvidia/pytorch:…...

python打卡DAY22

##注入所需库 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import random import numpy as np import time import shap # from sklearn.svm import SVC #支持向量机分类器 # # from sklearn.neighbors import KNeighborsClassifier …...

【教程】Docker更换存储位置

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 背景说明 更换教程 1. 停止 Docker 服务 2. 创建新的存储目录 3. 编辑 Docker 配置文件 4. 迁移已有数据到新位置 5. 启动 Docker 服务 6…...

鸿蒙Next API17学习新特性之组件可见区域变化事件新增支持设置事件的回调参数,限制它的执行间隔

概述 鸿蒙开发文档更新的非常快&#xff0c;对应我们开发者的学习能力也要求非常高&#xff0c;今天这篇文章给大家分享一下鸿蒙API17中更新的新特性学习。 鸿蒙 Next 的组件可见区域变化事件在最新的 API Version 17 中得到了增强&#xff0c;新增了支持设置事件的回调参数的…...

AI大模型从0到1记录学习 mysql day23

第 1 章 MySQL概述 1.1 基本概念 1.1.1 数据库是什么&#xff1f; 数据库&#xff08;DB&#xff1a;Database&#xff09;&#xff1a;存储数据的地方。 1.1.2 为什么要用数据库&#xff1f; 应用程序产生的数据是在内存中的&#xff0c;如果程序退出或者是断电了&#xff0c;…...

spring -MVC-02

SpringMVC-11 - 响应 在 SpringMVC 中&#xff0c;响应是服务器对客户端请求的反馈&#xff0c;它可以以多种形式呈现&#xff0c;包括视图名称、ModelAndView 对象、JSON 数据以及重定向等。以下是对 SpringMVC 中不同响应类型的详细介绍&#xff1a; 1. 视图名称 通过返回…...

深入解析 React 的 useEffect:从入门到实战

文章目录 前言一、为什么需要 useEffect&#xff1f;核心作用&#xff1a; 二、useEffect 的基础用法1. 基本语法2. 依赖项数组的作用 三、依赖项数组演示1. 空数组 []&#xff1a;2.无依赖项&#xff08;空&#xff09;3.有依赖项 四、清理副作用函数实战案例演示1. 清除定时器…...

通过Ollama读取模型

通过Ollama读取模型 前言一、查看本地Ollama上有哪些模型二、调用bge-m3模型1、调用模型2、使用bge-m3进行相似度比较 三、调用大模型 前言 手动下载和加载大模型通常需要复杂的环境配置&#xff0c;而使用Ollama可以避免这一问题。本文将介绍如何调用Ollama上的模型。 一、查…...

C#控制流

&#x1f9e9; 一、控制流概述 C# 中的控制流语句用于根据条件或循环执行代码块。它们是程序逻辑的核心部分。 ✅ 二、1. if、else if、else int score 85;if (score > 90) {Console.WriteLine("优秀"); } else if (score > 60) {Console.WriteLine("及…...