首页 > 其他分享 >springboot 接口限制访问频率

springboot 接口限制访问频率

时间:2024-04-23 17:36:32浏览次数:24  
标签:return springboot 接口 public 访问 requestCountMap key id

 

1. 自定义注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {

    //默认最大访问次数
    int value() default 3;

    //默认时间窗口(秒)
    long duration() default 60;
}

 

2. 创建拦截器处理频率逻辑

@Slf4j
public class RateLimitInterceptor implements HandlerInterceptor {

    private ConcurrentHashMap<String,Long> requestCountMap = new ConcurrentHashMap<>();

    @Override
    public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
        if (handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            RateLimit rateLimitAnnotation = handlerMethod.getMethod().getAnnotation(RateLimit.class);
            if (rateLimitAnnotation != null){
                long duration = rateLimitAnnotation.duration();
                int maxRequest = rateLimitAnnotation.value();
                String ipAddress = getClientIpAddress(request);
                String key = ipAddress + ":" + request.getRequestURI();

                //获取上一次请求的时间戳
                Long lastAccessTime = requestCountMap.getOrDefault(key, 0L);
                //获取当前请求的时间戳
                long currentAccessTime = System.currentTimeMillis();
                //计算时间间隔
                long timeInterval = TimeUnit.MILLISECONDS.toSeconds(currentAccessTime - lastAccessTime);
                //是否超过时间间隔
                if (timeInterval < duration){
                    //检查访问次数是否超过限制
                    if (requestCountMap.getOrDefault(key + "_count",0L) > maxRequest){
                        response.getWriter().write("访问频率超过限制");
                        response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
                        return false;
                    }
                }else {
                    //重置访问时间和访问次数
                    requestCountMap.put(key,currentAccessTime);
                    requestCountMap.put(key + "_count",0L);
                }
                //访问次数 + 1
                requestCountMap.put(key + "_count",requestCountMap.getOrDefault(key + "_count",0L) + 1);
            }
        }
        return true;
    }

    private String getClientIpAddress(HttpServletRequest request) {
        // 获取客户端IP地址的方法实现,可以根据具体的需求自行实现
        // 例如,可以通过HttpServletRequest对象获取IP地址
        // return request.getRemoteAddr();
        return "127.0.0.1"; // 这里仅作示例,假设IP地址为本地地址
    }
}

 

3. 添加拦截器

@Configuration
public class MyConfig  implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RateLimitInterceptor());
    }
}

 

4. 在接口上使用注解

    /**
     * 通过id查询项目任务书
     * @param id id
     * @return R
     */
    @Operation(summary = "通过id查询", description = "通过id查询")
    @GetMapping("/{id}" )
    @RateLimit
    public R getById(@PathVariable("id" ) String id) {
        return R.ok(prjAssignService.getByIdAssign(id));
    }

  在拦截器preHandler中,检查上次访问时间和当前时间的时间间隔,根据限制条件判断是否允许继续访问,超过限制则返回对应信息

 

标签:return,springboot,接口,public,访问,requestCountMap,key,id
From: https://www.cnblogs.com/homle/p/18153353

相关文章

  • mongdb未授权访问
    背景:mongdb未授权访问,解决方案是加认证。由于:安装好MongoDB数据库后,默认是【非授权模式】(也就是不需要任何权限验证、不需要验证账户,直接在命令窗口中输入mongo回车,就可以进行相关操作),这是非常不安全的所以:为了数据的安全,我们都应该去配置数据库的访问权限和修改默认(mongo......
  • Linux服务器中Docker部署的GitLab镜像访问出现500错误
    一背景这几天发现在Linux服务器中Docker部署的GitLab镜像访问出现500错误,在重启服务器后大概10分钟再次出现该情况,后面登录服务器一步步排查最终解决问题,现在将解决问题的过程做一个总结。二过程分析首先第一步就是看看我们Docker目录下文件占用的情况,因为我们的Linux服务......
  • 用edge_tts和Flask写一个语音生成接口
    1、安装Flask和edge_ttspipinstalledge-ttspipinstallflask[async]2、接口调用用application/json,POST参数:例子{"text":"现在是11:30分=,小爱提醒您,现在要出发了,请注意时间","lang":"zh-CN-YunxiNeural"}3、完整代码fromflaskimportFlask,requestim......
  • 修改 DNS 配置加速Github访问
    1.3、设置Hosts文件和刷新文件地址:C:\Windows\System32\drivers\etc\hosts文件权限:RightClick>Properties>Security  文件修改:注意域名后不要有  域名刷新(Windows):[cmd]ipconfig/flushdns(Mac):sudokillall-HUPmDNSResponder 1.4、配置IP和......
  • springboot 统计接口耗时及指定时间接口访问次数
     1.使用AOP在不改变原有方法的基础上对接口方法增强,引入依赖<!--引入AOP依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!--引入Redis依赖--><depen......
  • springboot项目找不到符号问题以及模块聚合项目maven插件使用的相关问题 问题如图
    参考:https://www.cnblogs.com/coderxiaobai/p/15005181.html问题:更换maven,清空缓存重新导入依赖依然无效后(1)解决方法:方式一:删除项目中.idea文件夹,重新打开项目,选中jdk版本,重新导入依赖即可。(2)如果不是上述的原因可能是项目是模块聚合项目,原因就是父工程的pom中存在maven插......
  • SpringBoot如何优雅的进行参数校验(一)
    SpringBoot如何优雅的进行参数校验一.为什么要进行参数校验在日常的开发过程中,我们常常需要对传入的参数进行校验,比如在web前后端分离项目中,参数校验有两个方面:前端进行参数校验后端进行参数校验那这两种有什么区别呢?只完成一个可不可以呢?答案是不可以的!......
  • SpringBoot的Cookie sameSite之坑
    https://blog.csdn.net/weixin_38296425/article/details/111941318 CSDN上很多文章给出了解决CookiesameSite坑跨域之坑的解决办法,但是都忽略了一个问题,没有给出相关的依赖,我也是费了不少劲终于找到了解决办法,在这里记录下来。例如下面的代码:@ConfigurationpublicclassT......
  • 62列表和元组访问速度对比
      importtimeimportrandom#python列表和元组通过千万级别的数据访问,对比耗时时间,元组访问速度不一定比列表快,还是列表略快过元组。defListTime():print('正在计算访问列表元素耗时时间')l=[iforiinrange(10000000)]t1=time.time()for_......
  • feign调用接口报错No qualifying bean of type '***HttpMessageConverters' available
    在整合springcloudgeateway时,调用了feign接口,报错Noqualifyingbeanoftype'org.springframework.boot.autoconfigure.http.HttpMessageConverters'available报错信息feign.codec.EncodeException:Noqualifyingbeanoftype'org.springframework.boot.autocon......