文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java如何实现接口限流

2023-06-21 20:27

关注

小编给大家分享一下Java如何实现接口限流,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

RateLimiter

Google开源工具包Guava提供了限流工具类RateLimiter,基于令牌桶算法实现。

1.maven依赖:

<dependency>    <groupId>com.google.guava</groupId>    <artifactId>guava</artifactId>    <version>27.1-jre</version></dependency>

2.自定义注解

import java.lang.annotation.*;import java.util.concurrent.TimeUnit;@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RequestLimiter {        double QPS() default 10D;        long timeout() default 500;        TimeUnit timeunit() default TimeUnit.MILLISECONDS;        String msg() default "请稍后再试!";}

3.拦截器

import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.google.common.util.concurrent.RateLimiter;import com.tiam.panshi.cloud.appback.annotation.RequestLimiter;import lombok.extern.slf4j.Slf4j;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;import java.io.PrintWriter;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;@Component@Slf4jpublic class RequestLimitingInterceptor implements HandlerInterceptor {    private final Map<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<>();    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {        //这里可以抽出去定义返回信息        JSONObject jsonObject = new JSONObject();        jsonObject.put("10001", "玩命加载中,请稍后再试");        try {            if (handler instanceof HandlerMethod) {                HandlerMethod handlerMethod = (HandlerMethod) handler;                RequestLimiter rateLimit = handlerMethod.getMethodAnnotation(RequestLimiter.class);                //判断是否有注解                if (rateLimit != null) {                    // 获取请求url                    String url = request.getRequestURI();                    RateLimiter rateLimiter;                    // 判断map集合中是否有创建好的令牌桶                    if (!rateLimiterMap.containsKey(url)) {                        // 创建令牌桶,以n r/s往桶中放入令牌                        rateLimiter = RateLimiter.create(rateLimit.QPS());                        rateLimiterMap.put(url, rateLimiter);                    }                    rateLimiter = rateLimiterMap.get(url);                    // 获取令牌                    boolean acquire = rateLimiter.tryAcquire(rateLimit.timeout(), rateLimit.timeunit());                    if (acquire) {                        //获取令牌成功                        return true;                    } else {                        log.warn("请求被限流,url:{}", request.getServletPath());                        makeResult(response, renderJson(jsonObject));                        return false;                    }                }            }            return true;        } catch (Exception var6) {            var6.printStackTrace();            makeResult(response, renderJson(jsonObject));            return false;        }    }    private void makeResult(HttpServletResponse response, JSONObject jo) {        response.setContentType("application/json; charset=utf-8");        response.setCharacterEncoding("UTF-8");        try (PrintWriter out = response.getWriter()) {            out.append(jo.toJSONString());        } catch (Exception e) {            e.printStackTrace();        }    }    private JSONObject renderJson(Object o) {        return JSONObject.parseObject(JSON.toJSONString(o));    }

4.注册拦截器

@Configurationpublic class WebMvcConfig extends WebMvcConfigurationSupport {          @Autowired     protected RequestLimitingInterceptor requestLimitingInterceptor;     @Override     public void addInterceptors(InterceptorRegistry registry) {         // 请求限流         registry.addInterceptor(requestLimitingInterceptor).addPathPatterns("/**");     }}

5.在接口上配置注解

@RequestLimiter(QPS = 5D, timeout = 200, timeunit = TimeUnit.MILLISECONDS,msg = "玩命加载中,请稍后再试")@GetMapping("/test")@ResponseBodypublic String test(){      return "";}

看完了这篇文章,相信你对“Java如何实现接口限流”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯