简单的针对某个接口进行限流,如果需要整体限流的话还是建议在网关上面或者服务器上面动手
Controller:


  @LimitRequest(count = 1,time = 60 * 1000 * 2)
  @PostMapping("limit")
  public String getLimitResult() {
   return "ok";
  }
Annotation:
  
  @Retention(RetentionPolicy.RUNTIME) // 运行时
  @Target({ElementType.TYPE, ElementType.METHOD}) // 可以被用在类及方法上
  @Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
  public @interface LimitRequest {

  /**
   * @return 允许的请求次数,默认 MAX_VALUE
   */
   int count() default Integer.MAX_VALUE;

  /**
   * @return 时间段,单位为毫秒数(和redis统一),默认 1分钟
   */
  int time() default 60 * 1000;
  
  /**
   * @return 触发限流之后抛出的异常信息
   */
   String meg() default "登记太频繁,请2分钟之后再次登记!";
  }

AOP:

  @Slf4j
  @Aspect
  @Component
  @Order(1)
  public class LimitRequestAop {
   @Autowired
   private RedisTemplate<String, String> redisTemplate;
  
   @Around("@annotation(limitRequest)")
  public Object doAround(ProceedingJoinPoint joinPoint, LimitRequest limitRequest) throws Throwable {
   // 获取当前请求对象
   ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
   boolean flag = true;
   HttpServletRequest request = attributes.getRequest();
      // String ipAddr = request.getRemoteAddr(); //根据自己需求来确定下面拼redis key值的时候要不要拼上客户端的ip
      // logger.info("ip" + ipAddr);
   String uri = request.getRequestURI();
  if (limitRequest != null) {
   flag = validRequestCount( uri.replace("/", "_"), limitRequest.count(), limitRequest.time());
   }
   if (flag) {
   return joinPoint.proceed();
   }
  
   throw new RuntimeException(limitRequest.meg());
   }

   /**
   * 判断某一个ip请求接口的次数是否超过限制
   *
  * @param uri 接口路径
  * @param limitCount 限流大小
  * @param timeOut 判断限流的时间
   * @return true 未限流 false 限流
   */
   private boolean validRequestCount(String uri, int limitCount, long timeOut) {
   try {
   // /api/queryInfo
   String redisKey = "req_limit_".concat(uri);
   long count = redisTemplate.opsForValue().increment(redisKey, 1);
   if (count == 1) {
   redisTemplate.expire(redisKey, timeOut, TimeUnit.MILLISECONDS);
  }
   if (count > limitCount) {
   return false;
  }
   } catch (Exception e) {
   return false;
   }
   return true;
   }

  }

 

对某个接口进行限流 以 Aop 注解的形式绑定接口 用redis实现的更多相关文章

  1. 服务接口API限流 Rate Limit 续

    一.前言 上一篇文章中粗浅的介绍使用Redis和基于令牌桶算法进行对服务接口API限流,本文介绍另一种算法---漏桶算法的应用.Nginx想必大家都有所了解是一个高性能的 HTTP 和反向代理服务器, ...

  2. Guava RateLimiter实现接口API限流

    一.简介 Guava提供的RateLimiter可以限制物理或逻辑资源的被访问速率.RateLimit二的原理类似与令牌桶,它主要由许可发出的速率来定义,如果没有额外的配置,许可证将按每秒许可证规定的 ...

  3. Google Guava缓存实现接口的限流

    一.项目背景 最近项目中需要进行接口保护,防止高并发的情况把系统搞崩,因此需要对一个查询接口进行限流,主要的目的就是限制单位时间内请求此查询的次数,例如1000次,来保护接口. 参考了 开涛的博客聊聊 ...

  4. 使用AOP和Semaphore对项目中具体的某一个接口进行限流

    整体思路: 一 具体接口,可以自定义一个注解,配置限流量,然后对需要限流的方法加上注解即可! 二 容器初始化的时候扫描所有所有controller,并找出需要限流的接口方法,获取对应的限流量 三 使用 ...

  5. 服务接口API限流 Rate Limit

    一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...

  6. java 服务接口API限流 Rate Limit

    一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...

  7. day74:drf:drf其他功能:认证/权限/限流/过滤/排序/分页/异常处理&自动生成接口文档

    目录 1.django-admin 2.认证:Authentication 3.权限:Permissions 4.限流:Throttling 5.过滤:Filtering 6.排序:OrderingF ...

  8. 实例:接口并发限流RateLimiter

    需求:接口每秒最多只能相应1个请求 1.创建 全局类对象 import com.google.common.util.concurrent.RateLimiter; import org.spring ...

  9. Guava-RateLimiter实现令牌桶控制接口限流方案

    一.前言 对于一个应用系统来说,我们有时会遇到极限并发的情况,即有一个TPS/QPS阀值,如果超了阀值可能会导致服务器崩溃宕机,因此我们最好进行过载保护,防止大量请求涌入击垮系统.对服务接口进行限流可 ...

  10. Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流

    最近管点闲事浪费了不少时间,感谢网友libinwalan的留言提醒.及时纠正路线,继续跟大家一起学习Spring Cloud Alibaba. Nacos作为注册中心和配置中心的基础教程,到这里先告一 ...

随机推荐

  1. 【Python&目标识别】labelimg报错IndexError: list index out of range

            博主在使用labelimg选取深度学习样本时,命令行报错IndexError: list index out of range,几经周折终于解决了,所以跟大家分享一下.         ...

  2. 理解ASP.NET Core - 全球化&本地化&多语言(Globalization and Localization)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 概述 在众多知名品牌的网站中,比如微软官网.YouTube等,我们经常可以见到"切换 ...

  3. 10分钟讲清int 和 Integer 的区别

    其实在Java编程中,int和Integer都是非常常用的数据类型,但它们之间存在一些关键的区别,特别是在面向对象编程中.所以接下来,就让我们一起来探讨下关于int和Integer的区别这个问题吧. ...

  4. 相较于Scrum, 我更推崇精益Kanban,帮助团队建立价值交付流,识别瓶颈问题

    最近在学习实践精益Kanban方法,结合自己团队实践Srum的经历,整理些资料二者的差异.相较于Scrum, 我更推崇精益Kaban. Agile是一套理论和原则,就像天边的北极星.Devops是一种 ...

  5. SQL Server 数据库字符串分割函数

    SQL Server 数据库字符串分割函数,源代码如下: ALTER FUNCTION [dbo].[f_split] ( @SourceStr VARCHAR(MAX), -- 源字符串 @Spli ...

  6. .Net8的AOT引导程序BootStrap

    前言 .Net8的本地预编机器码AOT,它几乎进行了100%的自举.微软为了摆脱C++的钳制,做了很多努力.也就是代码几乎是用C#重写,包括了虚拟机,GC,内存模型等等.而需要C++做的,也就仅仅是引 ...

  7. 2023河南省ICPC大学生程序设计竞赛-wh

    第一次出去比赛,首先感谢程老师选择我们新生更多的比赛机会,感谢! 在周六我们一起做了高铁出发取洛阳参加icpc河南省赛,不得不说洛阳师范学院确实环境很好看..在热身赛时,已经被泼了冷水,这C也太难了, ...

  8. 飞桨paddlespeech语音唤醒推理C定点实现

    前面的文章(飞桨paddlespeech语音唤醒推理C浮点实现)讲了飞桨paddlespeech语音唤醒推理的C浮点实现.但是嵌入式设备通常CPU频率低和memory小,在嵌入式设备上要想流畅的运行语 ...

  9. 2022-1-10 控件学习1 TextBlock、Lable、TextBox

    TextBlock LineBreak:在指定位置手动换行和<br/>类似 TextTrimming: CharacterEllipsis没有足够空间时显示...,WordEllpsis以 ...

  10. Vue报错:Invalid handler for event "changeUI": got undefined

    解决方案 错误代码如下所示: <router-view @hideBox="hideLoginRegisterBox" @changeUI="changeLogin ...