如何优雅的实现接口限流?

首先限流,其实解决方案有很多,比如通过nginx配置,通过gateway网关进行限流,比如Spring Cloud GateWay整合熔断器实现限流

但是以上都是全局的,如何灵活的针对某些接口进行不同级别的限流呢?

方案一:令牌桶

如何需要用到这个方案需要先了解漏桶算法和令牌桶算法的区别

引入依赖

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>18.0</version>
</dependency>

代码块

package com.sb.rateLimiter.service;import com.google.common.util.concurrent.RateLimiter;
import org.springframework.stereotype.Service;@Service
public class RateLimiterService {/*** 每秒只发出5个令牌*/RateLimiter rateLimiter = RateLimiter.create(5.0);/*** 尝试获取令牌* @return*/public boolean tryAcquire(){return rateLimiter.tryAcquire();}
}

自定义拦截器,在拦截器中实现限流

package com.sb.rateLimiter.interceptor;
import com.sb.rateLimiter.annotation.RateLimiterAnnotation;
import com.sb.rateLimiter.service.RateLimiterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class RateLimiterInterceptor implements HandlerInterceptor {@Resourceprivate RateLimiterService accessLimitService;private Logger logger = LoggerFactory.getLogger(RateLimiterInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (!(handler instanceof HandlerMethod)) {return true;}HandlerMethod handlerMethod = (HandlerMethod) handler;RateLimiterAnnotation rateLimiterAnnotation = handlerMethod.getMethod().getAnnotation(RateLimiterAnnotation.class);if(rateLimiterAnnotation == null) {return true;}if (!accessLimitService.tryAcquire()) {logger.info("限流中......");return false;}logger.info("请求成功");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

实现 WebMvcConfigurer 添加自定义拦截器

package com.sb.rateLimiter.config;
import com.sb.rateLimiter.interceptor.RateLimiterInterceptor;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;@SpringBootConfiguration
public class WebConfiguration implements WebMvcConfigurer {@Resourceprivate RateLimiterInterceptor rateLimiterInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(rateLimiterInterceptor).addPathPatterns("/**");}
}

自定义限流注解RateLimiterAnnotation

package com.sb.rateLimiter.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RateLimiterAnnotation {int rateLimiterNumber() default 1;
}

验证

package com.sb.rateLimiter.controller;
import com.sb.rateLimiter.annotation.RateLimiterAnnotation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api")
public class RateLimiterController {@RateLimiterAnnotation@RequestMapping(value = "/rateLimiterTest", method = RequestMethod.GET)public void rateLimiterTest() throws Exception {//业务逻辑;}

​​​​​​在这里插入图片描述

方案二:RedissonUtils.rateLimiter

这个方案其实和上面差不多都是通过一个注解实现接口限流的,只不过相较于上面的业务处理更加完善

自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimiter {//限流keyString key() default "rate_limit:";//限流时间,单位秒int time() default 60;//限流次数int count()default 100;//限流类型LimitType limitType() default  LimitType.DEFAULT
}

限流类型

public enum LimitType {// 默认策略全局限流DEFAULT,//根据请求者IP进行限流IP,//实例限流(集群多后端实例)CLUSTER

切面

@Befone("annotation(rateLimiter)")
public void doBefore(JoinPoint point, RateLimiter rateLimiter)//获取注解上的时间和计数int time = rateLimiter.time();int count = rateLimiter.count();//获取组合键String combineKey=this.getCombineKey(rateLimiter, point);try {//确定速率类型,这个枚举是redisson自带的枚举类RateType rateType = RateType.0VERALL;if(rateLimiter.LimiterType() == LimitType .CLUSTER){rateType  = RateType.PRE_CLIENT}// 调用RedissonUtils.rateLimiter方法进行限流处理Long number = RedissonUtils.rateLimiter(combineKey, rateType, count, time);if(number==-1){throw new RuntimeException("请求过于频繁~");};log.info("限制令牌 => {},剩余令牌 => {},緩存key =>'{}'"count,number,combineKey);}catch(Exception  e){throw new RnutimeException ("服务器限流异常,请稍后重试")}
}	
public String getCombineKey(RateLimiter rateLimiter, JoinPoint point){StringBuilder stringBuffer = new StringBuilder(rateLimiter.key());if(rateLimiter.limitType()== LimitType.IP){// 获取请求ipServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request =  attributes.getRequest();String clientIp =ServletUtil.getClientIP(request);stringBuffer.append(clientIP).append("-");}else if(rateLimiter.limitType() == LimitType.CLUSTER){//获取客户端实例idstringBuffer.append(RedissonUtils.getClient().getId()).append("-");MethodSignature signature =(MethodSignature)point.getSignature();Method method = signature.getMethod();Class<?>targetClass = method.getDeclaringClass();stringBuffer.append(targetClass.getName()).append(" ").append(method.getName());return stringBuffer.toString();}
}

RedissonUtils的限流方法


/*** redis 限流管理器* @author xxx* @version 1.0* @date xxx*/@Service
public class RedissonUtils{/*** 限流操作** @param key 限流key* @param rateType 限流类型* @param rate 速率* @param rateInterval  速率间隔*/public void rateLimiter(String key, Ratetype rateType,int ratel, int rateInterval) {// 创建限流器RRateLimiter rateLimiter = redisson.getRateLimiter(key);rateLimiter.trySetRate(rateType, rate,rateInterval,RateIntervalUtil.SECONDES);// 获取令牌if (rateLimiter.tryAcquire()){return rateLimiter.availablePermits();} else {return  -1 ;}}
}

使用

@RestController
public class TestController {@RateLimiter(time=5,count =2)@GetMapping("/testLimit")public ResultV0<String> test(string name){return ResultV0.ok( data:"success");}	
}	

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

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

相关文章

超标量处理器设计:重排序缓存(ROB)

★超标量处理器的很多地方用到了重排序缓存&#xff0c;但是我对它不是很了解&#xff0c;所以我整理一下重排序缓存的知识点。 重排序缓存(ROB)在确保乱序执行的指令能够正确地完成和提交(Commit)&#xff0c;也可以用来寄存器重命名。 ROB是一个先进先出的表&#xff0c;每个…

Re_Lasso

from sklearn.linear_model import LassoCV, Lasso import pandas as pd from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score from sklearn.model_selection import GridSearchCV# 读取数据…

【备战软考(嵌入式系统设计师)】10 - 软件工程基础

这一部分的内容是概念比较多&#xff0c;不要理解&#xff0c;去感受。 涉及的知识点是嵌入式系统开发和维护的部分&#xff0c;也就是和管理相关的&#xff0c;而不是具体如何进行嵌入式系统开发的细节。 系统开发生命周期 按照顺序有下面几个阶段&#xff0c;我们主要要记…

12 华三的二层链路聚合

12 华三的二层链路聚合 配置思路 1. 配置二层静态聚合组 (1) 进入系统视图。 system-view (2) 创建二层聚合接口&#xff0c;并进入二层聚合接口视图。 interface bridge-aggregation interface-number [ lite ] 创建二层聚合接口后&#xff0c;系统将自动生成…

代码随想录算法训练营DAY46|C++动态规划Part8|139.单词拆分、多重背包理论基础、背包问题总结篇

文章目录 139.单词拆分思路CPP代码 多重背包理论基础处理输入把所有个数大于1的物品展开成1个开始迭代&#xff0c;计算dp数组代码优化 背包问题总结篇 139.单词拆分 力扣题目链接 文章讲解&#xff1a;139.单词拆分 视频讲解&#xff1a;你的背包如何装满&#xff1f;| LeetCo…

计算方法实验9:Romberg积分求解速度、位移

任务 输出质点的轨迹 ( x ( t ) , y ( t ) ) , t ∈ { 0.1 , 0.2 , 0.3 , . . . , 10 } (x(t), y(t)), t\in \{0.1, 0.2, 0.3, ..., 10\} (x(t),y(t)),t∈{0.1,0.2,0.3,...,10}&#xff0c;并在二维平面中画出该轨迹.请比较M分别取4, 8, 12, 16, 20 时&#xff0c;Romberg积分达…

蓝桥杯省三爆改省二,省一到底做错了什么?

到底怎么个事 这届蓝桥杯选的软件测试赛道&#xff0c;都说选择大于努力,软件测试一不卷二不难。省赛结束&#xff0c;自己就感觉稳啦&#xff0c;全部都稳啦。没想到一出结果&#xff0c;省三&#xff0c;g了。说落差&#xff0c;是真的有一点&#xff0c;就感觉和自己预期的…

汽车软件研发工具链丨怿星科技新产品重磅发布

“创新引领未来”聚焦汽车软件新基建&#xff0c;4月27日下午&#xff0c;怿星科技2024新产品发布会在北京圆满举行&#xff01;智能汽车领域的企业代表、知名大企业负责人、投资机构代表、研究机构代表齐聚现场&#xff0c;线上直播同步开启&#xff0c;共同见证怿星科技从单点…

经典回溯算法之N皇后问题

问题描述&#xff1a; 有一个N*N的棋盘&#xff0c;需要将N个皇后放在棋盘上&#xff0c;保证棋盘的每一行每一列每一左斜列每一右斜列都最多只能有一个皇后。 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如…

Java | Leetcode Java题解之第71题简化路径

题目&#xff1a; 题解&#xff1a; class Solution {public String simplifyPath(String path) {String[] names path.split("/");Deque<String> stack new ArrayDeque<String>();for (String name : names) {if ("..".equals(name)) {if …

【基于 PyTorch 的 Python 深度学习】5 机器学习基础(3)

前言 文章性质&#xff1a;学习笔记 &#x1f4d6; 学习资料&#xff1a;吴茂贵《 Python 深度学习基于 PyTorch ( 第 2 版 ) 》【ISBN】978-7-111-71880-2 主要内容&#xff1a;根据学习资料撰写的学习笔记&#xff0c;该篇主要介绍了单 GPU 加速和多 GPU 加速&#xff0c;以及…

英语口语情景对话视频软件分享!

在当今全球化的时代&#xff0c;英语已成为一种通用的国际语言。为了提高英语口语能力&#xff0c;越来越多的人选择使用英语口语情景对话视频软件。本文将为您推荐几款备受欢迎的英语口语情景对话视频软件&#xff0c;帮助您轻松提高英语口语水平。 AI外语陪练 AI外语陪练软件…

已经有 Prometheus 了,还需要夜莺?

谈起当下监控&#xff0c;Prometheus 无疑是最火的项目&#xff0c;如果只是监控机器、网络设备&#xff0c;Zabbix 尚可一战&#xff0c;如果既要监控设备又要监控应用程序、Kubernetes 等基础设施&#xff0c;Prometheus 就是最佳选择。甚至有些开源项目&#xff0c;已经内置…

LoRA的原理简介

在文章开始前先澄清一个概念&#xff0c;需要区分形近的单词"LoRa"&#xff08;long range&#xff09;&#xff0c;这是一项通信技术。熟悉物联网行业的朋友相对会比较熟悉LoRa这项技术&#xff0c;因为有些设备比如电梯的控制就使用了这个技术进行本地数据和命令的…

小红书释放被封手机号 无限注册

前几年抖音也可以释放被封手机号 那时候都不重视 导致现在被封手机号想释放 基本不可能的 或者就是最少几百块 有专业的人帮你通过某些信息差释放 本教程是拆解 小红书被封手机号怎么释放&#xff0c;从今年开始&#xff0c;被封的手机号无法注销了 所以很困扰 那么本教程来…

基于一种改进小波阈值的微震信号降噪方法(MATLAB)

微震是指岩体由于在人为扰动或自然原因下受力变形&#xff0c;发生破裂过程中能量积聚而释放的弹性波或应力波。微震信号具有信噪比低、不稳定性、瞬时性和多样性等特点。因此&#xff0c;在任何损坏之前都会出现微小的裂缝&#xff0c;这种微小的裂缝是由岩层中应力和应变的变…

PPT职场课:话术+技巧+框架+案例,告别只会念PPT不会讲(8节课)

课程目录 001-讲PPT如何开场及导入?5个简单实用的方法.mp4 002-讲PPT如何过渡衔接结尾?6类话术争来就用.mp4 003-掌握这3个逻辑表达万能框架&#xff0c;搞定98的PPT.mp4 004-学会这3种PPT结构讲解技巧告别只会念不会讲(上).mp4 005-学会这3种PPT结构讲解技巧告别只会念…

Logstash分析MySQL慢查询日志实践

删除匹配到的行&#xff0c;当前行信息不记录到message中

106网页短信群发平台

什么是106网页短信群发平台&#xff1f; 106网页短信群发平台是一种便捷的在线群发工具&#xff0c;通过该平台用户可以方便地向大量的手机号码*。相比传统的群发方式&#xff0c;106网页群发平台具有更高效、更便捷的特点。 为什么选择106网页短信群发平台&#xff1f; 高效快…

浙大×移动云,携手点亮AI新时代

近年来&#xff0c;中国移动依托强大的算网资源优势&#xff0c;围绕大模型训练、推理和应用三大场景&#xff0c;打造了一站式智算产品体系。该体系旨在为客户提供覆盖资源、平台、应用的AI全链路服务。目前&#xff0c;一站式智算产品体系已在浙江大学智算中心和许昌中原智算…