SpringBoot单机限流的实现
作者:无敌少年小旋风
在系统运维中, 有时候为了避免用户的恶意刷接口, 会加入一定规则的限流,本文主要介绍了SpringBoot单机限流的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
谷歌的 RateLimiter 介绍
使用谷歌的 guava 包中 RateLimiter 类来实现,先来介绍一个这个类:
- RateLimiter 是一个频率限制器,通过配置频率来发放许可,如果 1 秒内可以访问十次,那么这十次许可发送的间隔是完全相同的
- 并发使用是安全的
- RateLimiter 还可以去配置先处于一个预热器,每秒增加发放的许可知道达到稳定的频率
- RateLimiter 不影响请求本身的节流,而是影响下一次请求的节流,比如当前任务如果占用许可较多,到达 RateLimiter 之后,会立即占用,当下一个请求到达 RateLimiter 时就会经历节流,因为上一个请求已经占用大量的许可。
一个小示例用法,如果想要发送一组数据,我们限制他在 5kb 每秒:
// 给每一个字节发放 1 个许可,限制在 5kb 每秒的话,只需要每秒发放 5000 个许可即可 final RateLimiter rateLimiter = RateLimiter.create(5000.0); void submitPacket(byte[] packet) { rateLimiter.acquire(packet.length); networkService.send(packet); }
使用 AOP 实现单机限流
实现步骤:
- 定义切面,拦截 Controller 层方法
- 创建一个 RateLimiter,定义访问频率
- 当执行方法时,发放一个许可,如果拿不到许可,直接拦截 Controller 层方法的执行,返回一个访问频繁的提示
Controller
@RestController @RequestMapping("/rate") public class RateController { @GetMapping public String testRate() { return "测试 Rate "; } }
切面
@Component @Aspect public class ServiceLogAspect { /** * 对 controller 限流 */ @Pointcut("execution(* com.javagpt.back.controller.*.*(..))") public void rateLimitPointCut() {} private static final RateLimiter rateLimiter = RateLimiter.create(10); @SneakyThrows // 使用之后不需要抛出异常,lombok会自动在编译时加上try/catch @Around("rateLimitPointCut()") public Object rateLimit(ProceedingJoinPoint joinPoint) { double rate = rateLimiter.getRate(); System.out.println(rate); if (rateLimiter.tryAcquire()) { return joinPoint.proceed(); } else { // 如果超出限流次数,拦截方法的执行,注意这里返回的对象要和 Controller 方法的返回对象类型相同,否则会报错 return "访问太过频繁"; } } }
到此这篇关于SpringBoot单机限流的实现的文章就介绍到这了,更多相关SpringBoot单机限流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!