首页 > 数据库 >限制IP对接口的调用频率_基于Redis实现

限制IP对接口的调用频率_基于Redis实现

时间:2023-08-01 10:11:35浏览次数:41  
标签:阈值 default IP 对接口 Redis Limit key TimeUnit MINUTES

pom.xml引入依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>

逻辑代码

	private boolean limitIpCallThis(String key) {
		Long increment = stringRedisTemplate.opsForValue().increment(key, 1);
		switch (increment.intValue()) {
			case 1:
				// 第一次调用,初始化过期时间60分钟
				stringRedisTemplate.expire(key, 60, TimeUnit.MINUTES);
				break;
			case 5:
				// 达到阈值后,刷新过期时间为5分钟
				stringRedisTemplate.expire(key, 5, TimeUnit.MINUTES);
				break;
			default:
				break;
		}
		return increment > 5;
	}

由请求方IP组成Redis的key,请求次数自增1。达到阈值5,即可通过此方法返回的true来提示请求者操作频繁

String.format("您的操作过于频繁,请%s分钟后再试! ", stringRedisTemplate.getExpire(key, TimeUnit.MINUTES))

这段代码可以放入Controller层的入口,也可结合AOP切面编程,给接口做调用频率限制。

AOP依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

 自定义注解

/**
 * 接口调用次数限制
 */
@Target(ElementType.METHOD) // 作用于方法
@Retention(RetentionPolicy.RUNTIME) // 生命周期
public @interface Limit {

    /**
     * 阈值,达到阈值拒绝请求
     */
    long threshold() default 0;

    /**
     * 重置时间,重置时间结束方解除限制
     */
    long reset() default 0;

    /**
     * 重置时间单位,默认分钟,可自定义设置
     */
    TimeUnit unit() default MINUTES;

}

 切面逻辑

    @Around("@annotation(xxxx.annotation.Limit)")
    public Object limit(ProceedingJoinPoint joinPoint) throws Throwable {
        // 取出注解实例
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Limit limit = method.getAnnotation(Limit.class);
        // TODO 根据接口Limit实例的阈值和重置时间做对应处理 (改动上文的limitIpCallThis方法,当该方法返回true抛出异常即可)
        ...
        return joinPoint.proceed();
    }

 使用示例

标签:阈值,default,IP,对接口,Redis,Limit,key,TimeUnit,MINUTES
From: https://www.cnblogs.com/ashet/p/17595699.html

相关文章

  • Redis 基础
    1.Redis入门1.1Redis简介Redis是一个基于内存的key-value结构数据库。Redis是互联网技术领域使用最为广泛的存储中间件。官网:https://redis.io中文网:https://www.redis.net.cn/key-value结构存储:主要特点:基于内存存储,读写性能高适合存储热点数据(热点商品、资讯、新闻......
  • iptables和firewalld开通策略日志
    我的iptables中有这个规则:iptables-AINPUT-s192.168.11.0/24-jLOG我的问题是:iptables日志文件在哪里,我该如何更改?这些日志由内核生成,因此它们将转到接收内核日志的文件: /var/log/kern.log 。如果要将这些日志重定向到其他文件,则无法通过iptables完成。它可以在调......
  • windows安装redis
    前言RemoteDictionaryServer(Redis)是一个开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的API,是跨平台的非关系型数据库。Redis通常被称为数据结构服务器,因为值(value)可以是字符串(Stri......
  • Java面试题 P24:Redis篇:redis集群有哪些方案?
    在Redis中提供的集群方案总共有三种:(1)主从模式(2)哨兵模式(3)分片集群redis主从数据同步的流程时什么?      ......
  • Java面试题 P25:Redis篇:redis是单线程的,但是为什么还那么快?
    一、Redis是单线程的,但是为什么还那么快1、Redis是纯内存操作,执行速度非常快2、采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题,加入并发锁,影响性能3、使用I/O多路复用模型,非阻塞IO二、你能解释一下I/O多路复用模型? ......
  • Java面试题 P23:Redis篇:redis分布式锁,是如何实现的?
       单台服务器:加synchronlzed解决方案。      (1)采用Watchdag给锁续期(2)抢不到锁的线程会尝试等待(3)所有的redis命令采用lua脚本,保证执行的原子性     ......
  • JavaScript
    1、什么是JavaScriptJavaScript是一门世界上最流行的脚本语言一个合格的后端人员,必须精通JavaScript历史:https://blog.csdn.net/kese7952/article/details/793578682、快速入门2.1、引入JavaScript1、内部标签<script>//......</script>2、外部标签abs.js//......
  • Java面试题 P22:Redis篇:Redis做为缓存,Redis的数据淘汰策略是什么?
          ......
  • Java面试题 P20:Redis篇:Redis做为缓存,数据的持久化是怎么做的?
    Redis做为缓存,数据的持久化是怎么做的?在Redis中提供了两种数据持久化的方式:1、RDB  2、AOF       ......
  • python解释器安装后,pip的设置步骤
    当python解释器安装好后,开发过程中势必要涉及第三方包的安装,那么由于pip自带的下载源是境外的,下载速度很慢(经常会下载失败)所以必须要先设置pip的全局下载源为国内镜像(这个具体看个人,我比较喜欢清华镜像源(豆瓣,阿里也都不错的)),具体如下:(1)打开cmd,输入pip,然后回车(这步的目的是确保我们......