zoukankan      html  css  js  c++  java
  • Spring mvc通过访问者IP限制接口访问频率

    https://blog.csdn.net/qq_31384551/article/details/80955215

    我们有的时候系统里面有的用户接口为了控制访问频率,需要使用到,笔记走一波

    环境:

    spring

    spring mvc

    Guava:谷歌高并发工具,下面是maven

    <!--谷歌guava高并发处理工具-->
    <dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
    </dependency>
    我们这次主要使用到的是Guava工具的LoadingCache 和 

    RateLimiter 即缓存和限流

     
    由于是在spring 环境中,所以就直接上Service代码了:


    /**
    * 接口访问限流service,此接口主要用于针对ip地址对于接口访问的限流控制
    */
    @Service
    public class LoadingCacheServiceImpl implements LoadingCacheService {
    LoadingCache<String, RateLimiter> ipRequestCaches = CacheBuilder.newBuilder()
    .maximumSize(200)// 设置缓存个数
    .expireAfterWrite(1, TimeUnit.DAYS)
    .build(new CacheLoader<String, RateLimiter>() {
    @Override
    public RateLimiter load(String s) throws Exception {
    return RateLimiter.create(0.2);// 新的IP初始化 (限流每秒0.1个令牌响应,即10s一个令牌)
    }
    });
    public RateLimiter getRateLimiter(String key) throws ExecutionException {
    return ipRequestCaches.get(key);
    }
    }
    控制器使用代码:

    @Controller
    @RequestMapping("/tool/upload/")
    public class FileUploadController{
    @Resource
    LoadingCacheService loadingCacheService;
    /**
    * ajax上传文件
    * @param file 文件对象
    * @return
    */
    @RequestMapping("ajaxUpload")
    @ResponseBody
    public AjaxRes ajaxUpload(@RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest){
    String ipAddr = IPUtil.getIpAddr(getRequest());
    try {
    RateLimiter limiter = loadingCacheService.getRateLimiter(ipAddr);
    if(limiter.tryAcquire()){
    //获得令牌(不限制访问)
    }else {
    //未获得令牌(限制访问)
    }
    } catch (ExecutionException e) {
    e.printStackTrace();
    }
    return res;
    }
    }
    注:主要就是把没一个用户IP的令牌桶RateLimiter给缓存起来,然后每次用户请求接口的时候就去拿一次令牌,那到令牌则不限制访问,没拿到则限制

    PS:第一次使用,哪里不对请指正,谢谢

    根据qq_35284533兄弟的提示,补充IPUtil工具类代码,这个工具类是用于获取IP地址的。

    package com.jufanshare.myblog.common.util;

    import javax.servlet.http.HttpServletRequest;

    /**
    * 获取客户端IP地址
    */
    public class IPUtil {

    /**
    * 客户端真实IP地址的方法一:
    */
    public static String getRemortIP(HttpServletRequest request) {
    if (request.getHeader("x-forwarded-for") == null) {
    return request.getRemoteAddr();
    }
    return request.getHeader("x-forwarded-for");
    }
    /**
    * 客户端真实IP地址的方法二:
    */
    public static String getIpAddr(HttpServletRequest request) {
    String ip="";
    if(request!=null){
    ip = request.getHeader("x-forwarded-for");
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getHeader("Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getRemoteAddr();
    }
    }
    return ip;
    }
    }
     

     
    ————————————————
    版权声明:本文为CSDN博主「聚繁大BUG」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_31384551/article/details/80955215

  • 相关阅读:
    Hybrid 实验
    Access+Trunk 配置
    JS 超类和子类
    javascript高级程序设计第3版——第一章概括
    js 获取getElementsTagName()方法返回值的内容
    js 数组的pop(),push(),shift(),unshift()方法小结
    js parseInt()与Number()区别
    HTML中引用外部JS文件失效原因
    TP5报错 User qdm813229266 already has more than 'max_user_connections' active connections 解决办法
    微信内打开链接,跳转到公众号关注页面
  • 原文地址:https://www.cnblogs.com/zhoading/p/12199780.html
Copyright © 2011-2022 走看看