当前位置:   article > 正文

SpingBoot简单限流插件开发_springboot限流可视化组件

springboot限流可视化组件

SpingBoot简单限流插件开发

一、限流方案

   1、 Google的Guava工具包中就提供了一个限流工具类——RateLimiter,本文也是通过使用该工具类来实现限流功能。RateLimiter是基于“令牌通算法”来实现限流的。

   2、目前返回信息是 json 格式的数据,如果需要 xml ,可以将返回的类型放到 配置文件中,根据需要定制 

   3、本文只给出核心代码,详细代码,前往码云查看:https://gitee.com/wsy_13926404489/spring-boot-learning

二、限流器实现

   1、导入 jar 包

  1. <dependency>
  2. <groupId>com.google.guava</groupId>
  3. <artifactId>guava</artifactId>
  4. <version>23.0</version>
  5. </dependency>

 

   2、继承WebMvcConfigurerAdapter来添加自定义拦截器,主要实现  addInterceptors(InterceptorRegistry registry) 方法

  1. @Override
  2. public void addInterceptors(InterceptorRegistry registry) {
  3. registry.addInterceptor(limitInterceptor)
  4. .addPathPatterns("/**");
  5. //.excludePathPatterns() 不拦截路径
  6. }

 

3、自定义拦截器,实现 HandlerInterceptor 接口,并在拦截器中实现限流

  1. /**
  2. * 处理请求之前(保证业务系统的稳定)
  3. * @param request
  4. * @param response
  5. * @param handler
  6. * @return
  7. * @throws Exception
  8. */
  9. @Override
  10. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  11. // 统一设置字符编码 (中文、UTF-8)
  12. response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
  13. response.setContentType("text/html; charset=UTF-8");
  14. // 限流
  15. boolean limit = limiter.tryAcquire();
  16. if(!limit){
  17. int code = Optional.ofNullable(limitProperties.getCode()).orElse(-1);
  18. String msg = Optional.ofNullable(limitProperties.getMsg()).orElse("服务繁忙,请稍后再试!");
  19. String result = "{\"msg\":\"" + msg + "\",\"code\":" + code +"}";
  20. response.getWriter().println(new String(result.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
  21. log.error("请求被拦截,返回消息:{}" , new String(result.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
  22. return false;
  23. }
  24. return true;
  25. }

 

4、实例化 RateLimiter 对象,用于拦截

  1. /**
  2. * 限流实例
  3. * @return
  4. */
  5. @Bean
  6. public RateLimiter getRateLimiter(@Autowired ApplicationContext applicationContext){
  7. //判断是否存在 limit.count 存在获取该值,且该值必须大于 0 ,不存在将该值设置为 int 的最大值(即不限流)
  8. int limitCount = DEFAULT_LIMITCOUNT;
  9. String limitCountStr = applicationContext.getEnvironment().getProperty("limit.count");
  10. if(!StringUtils.isEmpty(limitCountStr) && !Objects.equals(limitCountStr.trim(), "0")){
  11. if(Integer.parseInt(limitCountStr.trim()) > 0){
  12. limitCount = Integer.parseInt(limitCountStr.trim());
  13. }
  14. }
  15. log.info("配置的最大QPS: {}", limitCount);
  16. return RateLimiter.create(limitCount);
  17. }

 

5、将一些入参信息放到配置文件中,根据使用时需要

  1. @Data
  2. @ConfigurationProperties(prefix = "limit")
  3. @Component
  4. public class LimitProperties {
  5. // 每秒产生别的令牌数
  6. private Integer count;
  7. // 超时返回的消息(快速失败消息)
  8. private String msg;
  9. //返回给前端的编码()
  10. private Integer code;
  11. }

 

三、在项目中使用

   1、引入组件的 jar 

  1. <dependency>
  2. <groupId>org.example</groupId>
  3. <artifactId>limit-spring-boot-starter</artifactId>
  4. <version>1.0-SNAPSHOT</version>
  5. </dependency>

 


   2、添加必要的参数配置

  1.     limit.count # 最大 QPS
  2.     limit.msg   # 超时后返回给调用者的消息说明 
  3.     limit.code  # 超时返回调用者的响应码(不是 httpCode、不管请求是否拦截 httpCode 都是返回 200

 

3、新建一个 controller ,简单的接口即可,如下:

  1. @RestController
  2. public class LimitCtrl {
  3. @GetMapping("/limit")
  4. public JSONObject limit(){
  5. JSONObject result = new JSONObject();
  6. result.put("code", 0);
  7. result.put("msg", "请求成功");
  8. return result;
  9. }
  10. }

4、使用 JMeter 对测试接口进行压测,返回消息如下:

{"msg":"服务繁忙,请稍后再试!","code":1}

5、查看日志:

2021-05-24 14:38:42.440 ERROR 7976 --- [nio-8080-exec-7] c.w.limit.interceptor.LimitInterceptor   : 请求被拦截,返回消息:{"msg":"服务异常,请稍后再试!","code":1}

 

项目路径:https://gitee.com/wsy_13926404489/spring-boot-learning.git

 

 

 

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/784729
推荐阅读
相关标签
  

闽ICP备14008679号