- A+
所属分类:系统文档
Redis实现接口限流
发表于 2023-08-25 | 更新于 2023-08-25 | 字数统计: 5.9k | 阅读时长: 15分钟 | 阅读量: 16 | 后端笔记 |评论数: 0
准备
-
自定一个redis接口限流注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AccessLimit { /** * 单位时间(秒) * * @return int */ int seconds(); /** * 单位时间最大请求次数 * * @return int */ int maxCount(); } java
-
标记在你想要限流的接口上
@AccessLimit(seconds = 6, maxCount = 1) @ApiOperation(value = "发送邮箱验证码") @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String") @GetMapping("/users/code") public Result<?> sendCode(String username) { userAuthService.sendCode(username); return Result.ok(); } java
拦截
-
自定义限流拦截器AccessLimitHandler
/** * @author: ladidol * @date: 2022/11/28 12:25 * @description: 限流拦截器 */ @Log4j2 public class AccessLimitHandler implements HandlerInterceptor { @Autowired private RedisService redisService; @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception { // 如果请求输入方法 if (handler instanceof HandlerMethod) { HandlerMethod hm = (HandlerMethod) handler; // 获取方法中的注解,看是否有该注解 AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class); if (accessLimit != null) { long seconds = accessLimit.seconds(); int maxCount = accessLimit.maxCount(); // 关于key的生成规则可以自己定义 本项目需求是对每个方法都加上限流功能,如果你只是针对ip地址限流,那么key只需要只用ip就好 String key = IpUtils.getIpAddress(httpServletRequest) + hm.getMethod().getName(); // 从redis中获取用户访问的次数 try { // 此操作代表获取该key对应的值自增1后的结果 long q = redisService.incrExpire(key, seconds); if (q > maxCount) { render(httpServletResponse, Result.fail("请求过于频繁,请稍候再试")); log.warn(key + "请求次数超过每" + seconds + "秒" + maxCount + "次"); return false; } return true; } catch (RedisConnectionFailureException e) { log.warn("redis错误: " + e.getMessage()); return false; } } } return true; } /** * 作者:Ladidol * 描述:将不通过的结果返回给前端 */ private void render(HttpServletResponse response, Result<?> result) throws Exception { response.setContentType(APPLICATION_JSON); OutputStream out = response.getOutputStream(); String str = JSON.toJSONString(result); out.write(str.getBytes(StandardCharsets.UTF_8)); out.flush(); out.close(); } } java
-
在WebMvcConfigurer的实现类中注册拦截器
/** <p> * 作者:Ladidol * 描述:WebMvc注册拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { //注册限流拦截器 registry.addInterceptor(getAccessLimitHandler()); } java
另一种实现方式:[我司用了 6 年的 Redis 分布式限流器,可以说是非常厉害了! (qq.com)](
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
注意:本站用户发帖仅代表本站用户个人观点,并不代表本站赞同其观点和对其真实性负责。
本站资源多为网络收集,如涉及版权问题请及时与站长联系,我们会在第一时间内删除资源。
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫