api限流的场景

限流的需求出现在许多常见的场景中

  • 秒杀活动,有人使用软件恶意刷单抢货,需要限流防止机器参与活动
  • 某api被各式各样系统广泛调用,严重消耗网络、内存等资源,需要合理限流
  • 淘宝获取ip所在城市接口、微信公众号识别微信用户等开发接口,免费提供给用户时需要限流,更具有实时性和准确性的接口需要付费。

api限流实战

首先我们编写注解类AccessLimit,使用注解方式在方法上限流更优雅更方便!三个参数分别代表有效时间、最大访问次数、是否需要登录,可以理解为 seconds 内最多访问 maxCount 次。

Copyimport java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {int seconds();int maxCount();boolean needLogin() default true;
}

限流的思路

  • 通过路径:ip的作为key,访问次数为value的方式对某一用户的某一请求进行唯一标识
  • 每次访问的时候判断key是否存在,是否count超过了限制的访问次数
  • 若访问超出限制,则应response返回msg:请求过于频繁给前端予以展示
Copyimport org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class AccessLimtInterceptor implements HandlerInterceptor {@Autowiredprivate RedisService redisService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (handler instanceof HandlerMethod) {HandlerMethod hm = (HandlerMethod) handler;AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);if (null == accessLimit) {return true;}int seconds = accessLimit.seconds();int maxCount = accessLimit.maxCount();boolean needLogin = accessLimit.needLogin();if (needLogin) {//判断是否登录}String key = request.getContextPath() + ":" + request.getServletPath() + ":" + ip ;Integer count = redisService.get(key);if (null == count || -1 == count) {redisService.set(key, 1);redisService.expire(seconds);return true;}if (count < maxCount) {redisService.inCr(key);return true;}if (count >= maxCount) {//                response 返回 json 请求过于频繁请稍后再试return false;}}return true;}
}

注册拦截器并配置拦截路径和不拦截路径

Copyimport org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;// extends WebMvcConfigurerAdapter 已经废弃,java 8开始直接继承就可以
@Configuration
public class IntercepterConfig  implements WebMvcConfigurer {@Autowiredprivate AccessLimtInterceptor accessLimtInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(accessLimtInterceptor).addPathPatterns("/拦截路径").excludePathPatterns("/不被拦截路径 通常为登录注册或者首页");}
}

在Controller层的方法上直接可以使用注解@AccessLimit

Copyimport org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("test")
public class TestControler {@GetMapping("accessLimit")@AccessLimit(seconds = 3, maxCount = 10)public String testAccessLimit() {//xxxxreturn "";}
}

最后

感谢大家看到这里,文章有不足,欢迎大家指出;如果你觉得写得不错,那就给我一个赞吧。

也欢迎大家关注我的公众号:程序员麦冬,麦冬每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

Spring Boot如何使用Redis进行API防刷限流?相关推荐

  1. 高并发之API接口,分布式,防刷限流,如何做?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"加入公众号专属技术群 在开发分布式高并发系统时有三把利器用来保护系统:缓存.降级 ...

  2. api压测工具_高并发之API接口,分布式,防刷限流,如何做?

    在开发分布式高并发系统时有三把利器用来保护系统:缓存.降级.限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解 ...

  3. Spring Boot 集成 Swagger 生成 RESTful API 文档

    原文链接: Spring Boot 集成 Swagger 生成 RESTful API 文档 简介 Swagger 官网是这么描述它的:The Best APIs are Built with Swa ...

  4. Spring Boot之基于Redis实现MyBatis查询缓存解决方案

    转载自 Spring Boot之基于Redis实现MyBatis查询缓存解决方案 1. 前言 MyBatis是Java中常用的数据层ORM框架,笔者目前在实际的开发中,也在使用MyBatis.本文主要 ...

  5. 使用Spring Boot自动发布和监视API

    如果您正在沿着微服务风格的架构前进,那么您将需要接受的一个租户就是自动化. 这种架构风格介绍了许多活动部件. 如果成功,您的环境将具有大量服务API,企业可以将其用于应用程序开发和集成. 这意味着必须 ...

  6. Spring教程:使用Spring框架和Spring Boot创建Hello World REST API

    由于Java社区对早期版本的Enterprise Java感到失望,因此创建了Spring Framework . 从那时起,它已经发展成为一个巨大的生态系统,可以解决构建基于Web的Java应用程序 ...

  7. Spring Boot中使用Redis数据库

    Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elasticsearch, So ...

  8. spring boot 2.0 redis 分布式锁

    基于spring boot 2.0 redis 分布式锁,对于redis的一些基本配置及jar不做相关介绍,博客只是针对分布式锁使用. java代码: @Autowired private Redis ...

  9. Spring Boot 2 整合Redis哨兵模式

    Spring Boot 2 整合Redis哨兵模式除了配置稍有差异,其它与整合单实例模式类似,配置示例为 1. pom  文件 <parent><groupId>org.spr ...

最新文章

  1. linux下短链接出现TIME_WAIT耗尽端口号的解决方法
  2. Spring 与 Spring Boot 中的事件机制
  3. 在Ubuntu18.04上安装ros2的环境,ros2的常用命令:播放包、录制包等
  4. mysql mongodb qps_极高的QPS - DynamoDB与MongoDB相比其他noSQL?
  5. dropout理解(一)
  6. html点击按钮执行php代码,php代码在html文件里面执行的示例
  7. 分享25个新鲜出炉的 Photoshop 高级教程
  8. 表必须要有主键吗_玄关隔断什么材质好?玄关隔断必须要做吗?
  9. MAC电脑使用vue-cli脚手架搭建vue项目;mac使用脚手架vue-cli搭建vue项目
  10. 海康视频监控解决方案
  11. 3小时GIS入门教程(一):为什么要学GIS
  12. flash加载图片 代码_消失的人:Flash中的图片加载器和随机链接应用
  13. 本地电脑连接阿里云RDS云数据库
  14. 三种设计满足需求 网吧网络解决方案(转)
  15. Civil3D2018-01使用配置
  16. 百城巡展 | 人大金仓3月山海之约圆满收官
  17. 迷宫最短路径问题(数据结构4.4.3 拓展)
  18. 并发抢购 java_【转】京东抢购服务高并发实践
  19. java是什么?用来做什么的?
  20. HTML中的动画效果

热门文章

  1. c# -- List.AddRange()填坑
  2. 一个优秀的公众号运营者需要具备哪些能力?
  3. Ambari自动部署Hadoop集群实战
  4. 星梦缘陈彦妃_34岁陈彦妃近照,19岁凭《星梦缘》走红,生娃后才举办婚礼
  5. 导出java堆栈_jstack使用-倒出线程堆栈
  6. Servlet入门总结及第一个Servlet程序
  7. 函数式和面向对象编程有什么区别?
  8. phpcms入门模板配置文件修改
  9. 改善Python程序的91个建议
  10. 瑞芯微ITX-3588J开发板烧录ubuntu桌面系统(图文详解)