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

限制API接口访问速率

文章目录

  • 依赖
  • 注解
  • aop
  • helper
  • Test

免责声明:本人无意侵权,奈何找不到原文作者,也找不到网址,于是自己记录一下,如果有侵权之嫌,请联系我删除文章

依赖

  <!-- https://mvnrepository.com/artifact/com.google.guava/guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.3-jre</version></dependency>

注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface RateConfigAnno {String limitType();double limitCount() default 5d;
}

aop

import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.util.concurrent.RateLimiter;
import com.tjbchtyw.tjflowcontrol.annocation.RateConfigAnno;
import com.tjbchtyw.tjflowcontrol.helper.RateLimitHelper;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Objects;@Aspect
@Component
public class GuavaLimitAop {private static final Logger logger = LoggerFactory.getLogger(GuavaLimitAop.class);@Before("@annotation(com.tjbchtyw.tjflowcontrol.annocation.RateConfigAnno)")public void limit(JoinPoint joinPoint) {//1、获取当前的调用方法Method currentMethod = getCurrentMethod(joinPoint);if (Objects.isNull(currentMethod)) {return;}//2、从方法注解定义上获取限流的类型String limitType = currentMethod.getAnnotation(RateConfigAnno.class).limitType();double limitCount = currentMethod.getAnnotation(RateConfigAnno.class).limitCount();//使用guava的令牌桶算法获取一个令牌,获取不到先等待RateLimiter rateLimiter = RateLimitHelper.getRateLimiter(limitType, limitCount);//  boolean b =true;boolean pass = rateLimiter.tryAcquire();if (pass) {System.out.println("获取到令牌");}else {//重试 仅测试用 有优化方案可以放在评论区for (int i = 0; i < 5; i++) {ThreadUtil.safeSleep(1000);System.out.println("第" + (i + 1)  + "次获取令牌");if(rateLimiter.tryAcquire()) break;if(i == 4){System.out.println("在第" + (i + 1) +"次后未获取到令牌 开始限流");HttpServletResponse resp = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();JSONObject jsonObject=new JSONObject();jsonObject.put("success",false);jsonObject.put("msg","限流中");try {output(resp, jsonObject.toJSONString());}catch (Exception e){logger.error("error,e:{}",e);}}}}}private Method getCurrentMethod(JoinPoint joinPoint) {Method[] methods = joinPoint.getTarget().getClass().getMethods();Method target = null;for (Method method : methods) {if (method.getName().equals(joinPoint.getSignature().getName())) {target = method;break;}}return target;}public void output(HttpServletResponse response, String msg) throws IOException {response.setContentType("application/json;charset=UTF-8");ServletOutputStream outputStream = null;try {outputStream = response.getOutputStream();outputStream.write(msg.getBytes(StandardCharsets.UTF_8));} catch (IOException e) {e.printStackTrace();} finally {outputStream.flush();outputStream.close();}}
}

helper

import com.google.common.util.concurrent.RateLimiter;import java.util.HashMap;
import java.util.Map;public class RateLimitHelper {private RateLimitHelper(){}private static final Map<String,RateLimiter> rateMap = new HashMap<>();public static RateLimiter getRateLimiter(String limitType, double limitCount ){RateLimiter rateLimiter = rateMap.get(limitType);if(rateLimiter == null){rateLimiter = RateLimiter.create(limitCount);rateMap.put(limitType,rateLimiter);}return rateLimiter;}}

Test

@RestController@Tag(name = "测试Controller", description = "这是描述")@RequestMapping("/pred-api")public class FlowController {@AutowiredFlowContext flowContext;@PostMapping("/pdf/test")//Count 限制次数@RateConfigAnno(limitType = "makePdf",limitCount = 15)@Operation(summary = "限流接口")public String flowCont(@Parameter(name = "pdfParam", description = "参数对象,type标识执行不同的策略") @RequestBody Param Param) {return "test";}}

相关文章:

限制API接口访问速率

文章目录 依赖注解aophelperTest 免责声明&#xff1a;本人无意侵权&#xff0c;奈何找不到原文作者&#xff0c;也找不到网址&#xff0c;于是自己记录一下&#xff0c;如果有侵权之嫌&#xff0c;请联系我删除文章 依赖 <!-- https://mvnrepository.com/artifact/com.goo…...

广东省第三届职业技能大赛“网络安全项目”B模块--数字取证解析

广东省第三届职业技能大赛“网络安全项目”B模块任务书 PS: 关注鱼影安全第一部分 网络安全事件响应第二部分 数字取证调查任务 3: 网络数据包分析取证解析:第三部分 应用程序安全:需要环境可以私信博主~PS: 关注鱼影安全 模块 B 竞赛项目试题 本文件为:广东省第三届职业技…...

全链路压力测试:现代软件工程中的重要性

全链路压力测试不仅可以确保系统在高负载下的性能和稳定性&#xff0c;还能帮助企业进行有效的风险管理和性能优化。在快速发展的互联网时代&#xff0c;全链路压力测试已成为确保软件产品质量的关键步骤。 1、测试环境搭建 测试应在与生产环境尽可能相似的环境中进行&#xff…...

【计算机网络】难点、易遗忘点总结

文章目录 1. 单工通信、半双工通信和全双工通信2. TCP的三次握手和四次挥手 1. 单工通信、半双工通信和全双工通信 主要区别在于信息传输的方向和时间安排。单工通信是指信息只能在一个方向上传输的通信方式。半双工通信允许信息在两个方向上传输&#xff0c;但在任何给定的时…...

谷达冠楠科技:抖音开网店新手小白可以卖的产品

随着互联网的发展&#xff0c;越来越多的人选择在网上开设自己的店铺。而抖音作为目前最火的短视频平台&#xff0c;也提供了开店的功能。那么&#xff0c;对于新手小白来说&#xff0c;抖音开网店可以卖哪些产品呢? 我们可以考虑的是服装类商品。抖音上有很多时尚博主&#x…...

爬虫案例—根据四大名著书名抓取并存储为文本文件

爬虫案例—根据四大名著书名抓取并存储为文本文件 诗词名句网&#xff1a;https://www.shicimingju.com 目标&#xff1a;输入四大名著的书名&#xff0c;抓取名著的全部内容&#xff0c;包括书名&#xff0c;作者&#xff0c;年代及各章节内容 诗词名句网主页如下图&#x…...

阿里云容器服务助力万兴科技 AIGC 应用加速

作者&#xff1a;子白&#xff08;顾静&#xff09; 2023 年堪称是 AIGC 元年&#xff0c;文生图领域诞生了 Stable Diffusion 项目&#xff0c;文生文领域诞生了 GPT 家族。一时间风起云涌&#xff0c;国内外许多企业投身 AIGC 创新浪潮&#xff0c;各大云厂商紧随其后纷纷推…...

STM32F103标准外设库——认识STM32(一)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…...

设计模式——1_5 享元(Flyweight)

今人不见古时月&#xff0c;今月曾经照古人 ——李白 文章目录 定义图纸一个例子&#xff1a;可以复用的样式表绘制表格降本增效&#xff1f;第一步&#xff0c;先分析 变化和不变的地方第二步&#xff0c;把变化和不变的地方拆开来第三步&#xff1a;有没有办法共享这些内容完…...

kafka系列(二)

本章承接kafka一内容&#xff0c;文章在本人博客主页都有&#xff0c;可以自行点击浏览。 幂等性 请求执行多次&#xff0c;但执行的结果是一致的。 如果&#xff0c;某个系统是不具备幂等性的&#xff0c;如果用户重复提交了某个表格&#xff0c;就可能会造成不良影响。例如…...

Ubuntu20.04安装配置OpenCV-Python库并首次执行读图

一、选择三方提供的预编译包安装&#xff1a; 可以从官网下载 OpenCV 的安装包&#xff0c;编译后使用&#xff1b;也可以直接使用第三方提供的预编译包 安装。显然后者不需要执行编译步骤&#xff0c;更便捷。选择由 PyPI 提供的 OpenCV 安装包&#xff0c;可以在 https://py…...

经典目标检测YOLO系列(二)YOLOV2的复现(2)正样本的匹配、损失函数的实现及模型训练

经典目标检测YOLO系列(二)YOLOV2的复现(2)正样本的匹配、损失函数的实现及模型训练 我们在之前实现YOLOv1的基础上&#xff0c;加入了先验框机制&#xff0c;快速的实现了YOLOv2的网络架构&#xff0c;并且实现了前向推理过程。 经典目标检测YOLO系列(二)YOLOV2的复现(1)总体…...

半波整流电路原理详解+参数与计算公式

什么是半波整流电路&#xff1f; 半波整流电路的基本操作非常简单&#xff0c;输入信号通过二极管&#xff0c;由于只能通过一个方向的电流&#xff0c;二极管的整流作用&#xff0c;单个二极管只允许通过一半的波形。 下图说明了半波整流电路的基本原理。 半波整流电路工作图…...

GZ036 区块链技术应用赛项赛题第3套

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷&#xff08;3卷&#xff09; 任 务 书 参赛队编号&#xff1a; 背景描述 新能源作为新兴领域&#xff0c;产业呈现碎片化与复杂化的特性&#xff0c;逐渐出现管理困难、供应链金融、可信监管与数…...

LeetCode142.环形链表II

力扣题目链接 思路&#xff1a;判断链表是否有环&#xff1f;可以使用快慢指针法&#xff0c;快指针每次走两步&#xff0c;慢指针每次走一步&#xff0c;如果链表有环一定会在环中相遇。 如何找环的入口&#xff1f;当快慢指针在环中第一次相遇时&#xff0c;让快指针从头结…...

触摸按键控制LED灯

目录 1.理论 2.代码 2.1 touch_ctrl_led.v 2.2 tb_touch_ctrl_led 1.理论 以上的波形图的touch_flag是采用组合逻辑的方式产生的。 以上的touch_flag是采用时序逻辑产生的&#xff0c;时序逻辑会延迟一拍。 以上是上升沿和下降沿的组合逻辑和时序逻辑实现&#xff0c;逻辑或…...

QT自定义控件0-360°刻度尺

支持0到360&#xff0c;360到0的过度。 直接上代码&#xff0c;可以直接用&#xff0c;使用的paintevent事件实现的&#xff0c;没啥好讲的。 .cpp void Widget::drawCourse(QPainter& p,QPen pen,QFont font) {double currentNumber m_ang;p.setBrush(Qt::black);p.dra…...

c语言0基础笔记

目录 前言 第01章_C语言入门 1.1初识计算机语言 1.2初识C语言 1.3第一个c程序 1.4IDE使用 1.5注释 1.6第一个c程序剖析 1.7printf()输出格式 第02章_变量与进制 2.1关键字 2.2标识符 2.3变量 2.4基本数据类型的使用 2.5变量间的运算规则 2.6常量 2.7输入/输出函…...

Vue 中 Element UI 的 el-table 组件实现动态表头和内容

在 Vue 中使用 Element UI 的 el-table 组件时&#xff0c;为了实现动态表头&#xff08;包括第一层表头及其下的嵌套表头或子表头&#xff09;。需要后端返回的数据结构能够体现表头层级关系以及对应的数据结构相匹配。这样的数据通常是一个嵌套数组&#xff0c;每个表头单元可…...

安装sqlserver后—无法连接到 127.0.0.1,1433\sqlexpress

报错问题如下&#xff1a; 标题: 连接到服务器 ------------------------------ 无法连接到 127.0.0.1,1433\sqlexpress。 ------------------------------ 其他信息: 登录失败。该登录名来自不受信任的域&#xff0c;不能与 Windows 身份验证一起使用。 (Microsoft SQL Serve…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...