控制单位时间内接口的访问量

使用redis计数来控制单位时间内对某接口的访问量,防止刷验证码接口之类的。

使用自定义注解的方式,在需要被限制访问频率的方法上加注解即可控制。

看实现方式,基于springboot,aop,redis。

新建Springboot工程,引入redis,aop。

创建注解

package com.xueliang.annotation;import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;import java.lang.annotation.*;/*** Created by xueliang on 17/7/6.*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
//最高优先级
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RequestLimit {/*** 允许访问的次数*/int count() default 5;/*** 时间段,多少时间段内运行访问count次*/long time() default 60000;}

Aspect切面处理逻辑

package com.xueliang.aspect;import com.xueliang.annotation.RequestLimit;
import com.xueliang.util.HttpRequestUtil;
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.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;/*** Created by xueliang on 17/7/6.*/
@Component
@Aspect
public class RequestLimitAspect {private final Logger logger = LoggerFactory.getLogger(getClass());@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Before("execution(public * com.xueliang.controller.*.*(..)) && @annotation(limit)")public void requestLimit(JoinPoint joinpoint, RequestLimit limit) {// 接收到请求,记录请求内容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String ip = HttpRequestUtil.getIpAddr(request);String url = request.getRequestURL().toString();String key = "req_limit_".concat(url).concat(ip);//加1后看看值long count = redisTemplate.opsForValue().increment(key, 1);//刚创建if (count == 1) {//设置1分钟过期redisTemplate.expire(key, limit.time(), TimeUnit.MILLISECONDS);}if (count > limit.count()) {logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.count() + "]");throw new RuntimeException("超出访问次数限制");}}
}

获取IP的工具类

package com.xueliang.util;import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;/*** Created by xueliang on 17/7/6.*/
public class HttpRequestUtil {/*** 获取当前网络ip** @param request* @return*/public static String getIpAddr(HttpServletRequest request) {String ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {//根据网卡取本机配置的IPInetAddress inet = null;try {inet = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}ipAddress = inet.getHostAddress();}}//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}return ipAddress;}
}

通过Controller验证

@RestController
public class IndexController {@RequestLimit(count = 4)@GetMapping("/index")public Object index() {return 1;}
}

启动工程,使用jmeter多次访问index看看效果即可。

代码示例:使用redis计数来控制单位时间内对某接口的访问量相关推荐

  1. 使用redis incr计数来控制单位时间内对某接口的访问量

    控制单位时间内接口的访问量 使用redis incr计数来控制单位时间内对某接口的访问量,防止刷验证码接口之类的. 使用自定义注解的方式,在需要被限制访问频率的方法上加注解即可控制. 看实现方式,基于 ...

  2. wait 和 waitpid 详解及代码示例

    wait 和 waitpid 详解及代码示例 1. 父子进程处理历史及父进程处理方法 2. wait 2.1 wait 功能 2.2 wait 接口 2.3 wait 原理 2.3.1 wait 源码 ...

  3. eoLinker-API_Shop_验证码识别与生成类API调用的代码示例合集:六位图片验证码生成、四位图片验证码生成、简单验证码识别等...

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 六位图片验证码生成:包括纯数字.小写字母.大写字母.大小写混合.数 ...

  4. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入代码示例 )

    文章目录 总结 一.Android 事件依赖注入示例 1.创建依赖注入库 2.声明注解 (1).修饰注解的注解 (2).修饰方法的注解 3.Activity 基类 4.动态代理类调用处理程序 5.依赖 ...

  5. 【IOC 控制反转】Android 视图依赖注入 ( 视图依赖注入步骤 | 视图依赖注入代码示例 )

    文章目录 总结 一.Android 视图依赖注入步骤 二.Android 布局依赖注入示例 1.创建依赖注入库 2.声明注解 3.Activity 基类 4.依赖注入工具类 5.客户端 Activit ...

  6. php控制文本换行,css如何控制文字换行方式?(代码示例)

    css如何控制文字换行方式?本篇文章就给大家介绍css设置文字(特别是连续的数字和英文)强制换行.强制不换行且隐藏超出部分的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. 一. ...

  7. jedispool redis哨兵_通过java哨兵JedisSentinelPool代码示例连接对配置的redis哨兵主从模式进行测试验证...

    一.前言 本文章通过关于java的jedis(2.6.0)的redis客户端连接驱动包,对配置的redis哨兵+主从读写模式配置进行示例代码验证,详细参见具体配置步骤&示例代码说明部分. 二. ...

  8. python连接redis哨兵_Python redis.sentinel方法代码示例

    本文整理汇总了Python中redis.sentinel方法的典型用法代码示例.如果您正苦于以下问题:Python redis.sentinel方法的具体用法?Python redis.sentine ...

  9. java事务代码_关于java中实现JDBC事务控制代码示例

    一.前言 数据库事务是执行业务的每个逻辑单元一系列操作,可由一个或多个SQL语句组成.如执行的SQL都能被正确的执行,则这批SQL提交将被生效,否则都不成功,通过这样的事务控制有效的保障了数据库数据的 ...

最新文章

  1. 在Clojure中使用class
  2. 第二周课堂小结以及习题思考
  3. 使用springcloud gateway搭建网关(分流,限流,熔断)
  4. 第三期CSIG图像图形学科前沿讲习班-详细日程
  5. python实战讲解_Python数据可视化实战讲解
  6. CF618F Double Knapsack 构造、抽屉原理
  7. exe文件注册服务的方法
  8. [Bzoj1597][Usaco2008 Mar]土地购买(斜率优化)
  9. MySQL Replicaction Error 一例
  10. 【实用】CSS Border使用小分享——盒模型
  11. 使用注册表屏蔽任意按键或改键
  12. 9012 年了,Array 数组的方法赶紧用起来!
  13. 【CNN+VIT】LocalViT: Bringing Locality to Vision Transformers
  14. android 国际化之Locale
  15. 闰年和平年的区别python_利用Python实现图书超期提醒
  16. 中国医科大学2021年12月《五官科护理学》作业考核试题
  17. 路由器可以当交换机用吗
  18. 股份有限公司的章程包括哪些内容?
  19. ionic2实现通讯录,联系人搜索功能
  20. 机房建设必须知道的四大要求

热门文章

  1. GitHub 热榜:这款开源神器可帮您将文本转换为手写文字,并下载为 PDF 格式文件!...
  2. 科普:目标检测Anchor是什么?怎么科学设置?[附代码]
  3. 报名|极市X机器之心 2018计算机视觉最具潜力开发者榜单
  4. Spring源码解析-applicationContext.xml加载和bean的注册
  5. 基于蚂蚁金服「如何管理好10万行代码」搭建了 Vue 项目架构
  6. Jenkisn之JDK-MVN-ANT-GRADLE
  7. 【LeetCode】70 - Climbing Stairs
  8. Oracle EBS-SQL (PO-13):检查采购物料无一揽子协议价格.sql
  9. asp.net 路径(转)
  10. MongoDB中如何优雅地删除大量数据