利用AOP切面和redis记录目前接口访问量,超过访问上限便拒绝

记录一下目前接口的访问量,超过一定访问数量就拒绝之后的访问

添加这个注解放在controller上,进行接口的控制

@Target({ElementType.METHOD})
@Retention(RetrntionPolicy.RUNTIME)
@Documented
public @interface ReportOperation{
    /* 操作类型,导入,导出,查询,其他*/
    ReportOperationEnum operationType() default ReportOperationEnum.OTHER;
}

枚举类

public enum ReportOperationEnum{
    IMPORT,EXPORT,QUERY,OTHER
}

添加具体的切面逻辑

@Configuration
@Aspect
public class ReportInterceptor{

@Autowired
RedisTemplate redisTemplate;

//redis里面存储的key
private static final String REPORT_LIMIT="reportLimit";

//拦截所有的使用了这个注解的接口
@Befor("@annotation(reportOperation)")
public void before(ReportOperation reportOparation){
    ReportOperationEnum operationType=reportOparation.operationType();
    BoundZsetOperations boundZsetOperations=redisTemplate.boundZsetOps(REPORT_LIMIT);
    if(ReportOperationEnum.IMPORT.equals(operationType)){
          if(boundZsetOperations.score(ReportOperationEnum.IMPORT)!=null&&boundZsetOperations.score(ReportOperationEnum.IMPORT)>=1){
    throw new BusinessException("当前有用户正在进行导入操作,请稍后");
}
boundZSetOperations.incrementScore(ReportOperationEnum.IMPORT,1);
}else if(ReportOperationEnum.EXPORT.equals(operationType)){
    if(boundZsetOperations.score(ReportOperationEnum.EXPORT)!=null&&boundZsetOperations.score(ReportOperationEnum.EXPORT)>=1){
    throw new BusinessException("当前有用户正在进行导出操作,请稍后");
}
boundZSetOperations.incrementScore(ReportOperationEnum.EXPORT,1);
}else if(ReportOperationEnum.QUERY.equals(operationType)){
    if(boundZsetOperations.score(ReportOperationEnum.QUERY)!=null&&boundZsetOperations.score(ReportOperationEnum.QUERY)>=5){
    throw new BusinessException("当前多个用户正在查询,请稍后");
}
boundZSetOperations.incrementScore(ReportOperationEnum.QUERY,1);
}
redisTemplate.expire(REPORT_LIMIT,30,TimeUnit.MINUTES);
}

@After("@annotation(reportOperation)")
public void after(ReportOperation reportOparation){
    ReportOperationEnum operationType=reportOparation.operationType();
    BoundZsetOperations boundZsetOperations=redisTemplate.boundZsetOps(REPORT_LIMIT);
    if(ReportOperationEnum.IMPORT.equals(operationType)){
       boundZSetOperations.incrementScore(ReportOperationEnum.IMPORT,-1);
}else if(ReportOperationEnum.EXPORT.equals(operationType)){
boundZSetOperations.incrementScore(ReportOperationEnum.EXPORT,-1);
}else if(ReportOperationEnum.QUERY.equals(operationType)){
boundZSetOperations.incrementScore(ReportOperationEnum.QUERY,-1);
}

}



}

使用例子;

@RestController
@RequestMapping("test")
public class TestController{

@RequestMapping(value="/test1" ,method=RequestMethod.POST)
@ReportOperation(operationType=ReportOperationEnum.QUERY)//使用对应的注解拦截
public String test(){
    return "这个controller方法之后的逻辑就会拦截并且添加进redis进行访问记录了";
}

} 

  • 17
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值