ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

过滤器限流,接口防刷,线程安全

2020-06-10 14:38:32  阅读:456  来源: 互联网

标签:ConcurrentHashMap 防刷 MyFilter 接口 限流 线程 过滤器 lastTime public


因为这个涉及到公司安全漏洞,确实很大隐患,情况描述就抽象一些
情景描述:我们项目中一个很重要的接口,条件限制全部通过是操作redis的读写,与服务器上配置表数据进行判断比较。
因为这个接口很重要,也很敏感。刚好最近在摸索JMEMTER的使用,心想刚好可以测试下,并发的访问下我这个接口,我们的限制能够生效嘛?(这个疑问之前就想过,我们的redis读写操作,不具有原子性。但是我们老大告诉我,Redis的操作很快,不会出现限制不住的问题)
在这里插入图片描述
2千个并发,100~200多个请求都没有限制住。

解决思路

我想到三种方式

  1. 接口的最前面,用ConcurrentHashMap 做一个计时器。同一用户不能在多少秒内重复访问
  2. 拦截器的方式
  3. 过滤器的方式
    因为我们的限制条件都在Redis上,在线上环境已经出现过几次问题,导致我们的限制也没有生效。我思考解决问题的方式时,就避开了再用Redis。
    结合我项目的结构,最后我选择了使用过滤器的方式。
过滤器+ConcurrentHashMap 接口限流

我讲过滤器的代码贴上

**
 * @Author yjc
 * @Date 2020/6/6 10:01
 */
public class MyFilter implements Filter {

  	protected Logger log = Logger.getLogger(MyFilter.class);
    private static final long SECOND = 1000;
    /**
     * 用户访问的时间
     */
    private ConcurrentHashMap<String,Long> userVisitTime = new ConcurrentHashMap<>(16);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)  {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
         /**
         * 用户的唯一标识
         */
        String key = request.getParameter("userId");
        try{
            Long lastTime = userVisitTime.get(key);
            if (lastTime != null && lastTime+SECOND <= System.currentTimeMillis()){
                userVisitTime.put(key, System.currentTimeMillis());
                filterChain.doFilter(servletRequest,servletResponse);
            }else if (lastTime == null){
                userVisitTime.put(key, System.currentTimeMillis());
                filterChain.doFilter(servletRequest,servletResponse);
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
    }

    @Override
    public void destroy() {

    }
}

同时还需要再web.xml添加上,我只做了这个重要接口的限制

	<filter>
        <filter-name>myFileter</filter-name>
        <filter-class>com.mini.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myFileter</filter-name>
        <url-pattern>/data/xx.action</url-pattern>
    </filter-mapping>

下面给大家测试一下,同样的2000个并发,我接口的开始打印了消息,下面是测试结果
在这里插入图片描述

设计缺陷

当然这样设计也有很大的问题,如果用户量达到100w,这个ConcurrentHashMap内存占用会不断增大。

还请各位大佬,提出批评指正!

标签:ConcurrentHashMap,防刷,MyFilter,接口,限流,线程,过滤器,lastTime,public
来源: https://blog.csdn.net/qq_45186545/article/details/106646963

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有