首页 > 其他分享 >通过Guava实现ip限流访问

通过Guava实现ip限流访问

时间:2024-11-08 16:09:30浏览次数:4  
标签:10 return ip 访问 限流 import Guava public

一分钟内某个ip请求制定接口超过10次,则禁止该ip 10分钟内不能访问,通过Guava实现一个拦截器,拦截指定接口来处理

 

mport com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class IpAccessLimit {

    private final Cache<String, AtomicInteger> ipRequestCounts;
    private final Cache<String, Boolean> bannedIps;

    public IpAccessLimit() {
        // 设置缓存过期时间为1分钟
        this.ipRequestCounts = CacheBuilder.newBuilder()
                .expireAfterWrite(1, TimeUnit.MINUTES)
                .build();

        // 设置禁止访问的缓存过期时间为10分钟
        this.bannedIps = CacheBuilder.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .build();
    }

    /**
     * 检查IP是否可以访问
     *
     * @param ip IP地址
     * @return 如果可以访问返回true,否则返回false
     */
//    public boolean canAccess2(String ip) {
//        RateLimiter rateLimiter = ipRateLimiters.getIfPresent(ip);
//        if (rateLimiter == null) {
//            // 初始化新的限流器,每秒最多允许10次请求
//            rateLimiter = RateLimiter.create(10.0/60.0);
//            ipRateLimiters.put(ip, rateLimiter);
//        }
//        return rateLimiter.tryAcquire();
//    }


    /**
     * 检查IP是否可以访问
     *
     * @param ip IP地址
     * @return 如果可以访问返回true,否则返回false
     */
    public boolean canAccess(String ip) {
        // 检查是否在禁止访问列表中
        if (bannedIps.getIfPresent(ip) != null) {
            return false;
        }

        AtomicInteger requestCount = ipRequestCounts.getIfPresent(ip);
        if (requestCount == null) {
            requestCount = new AtomicInteger(0);
            ipRequestCounts.put(ip, requestCount);
        }

        int count = requestCount.incrementAndGet();

        // 如果当前分钟内的请求次数超过10次
        if (count > 10) {
            // 将该IP加入到禁止访问列表中
            bannedIps.put(ip, true);
            return false;
        }

        return true;
    }
}

 

mport javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import java.util.regex.Pattern;

public class IpAccessFilter implements Filter {

    private static final IpAccessLimit ipAccessLimit = new IpAccessLimit();

    protected final Logger log = LoggerFactory.getLogger(IpAccessFilter.class);

    private Pattern limitedUrlPattern;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化需要限制的URL模式
        limitedUrlPattern = Pattern.compile(".*LoginAction\\.action$");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // 将 ServletResponse 转换为 HttpServletResponse
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

        String IPAddr = Browser.getIpAddr(request);
        String requestURI = request.getRequestURI();

        // 只对特定的URL进行访问次数限制
        if (limitedUrlPattern.matcher(requestURI).matches()) {
            if (ipAccessLimit.canAccess(IPAddr)) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                log.error("Too many requests from this IP address: {}",IPAddr);
                // 处理超出访问次数的情况,例如返回429 Too Many Requests状态码
                httpResponse.setStatus(429);
                httpResponse.getWriter().write("Too many requests, please try again later!");
            }
        } else {
            // 对其他URL不做限制,直接放行
            filterChain.doFilter(request, servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

 

标签:10,return,ip,访问,限流,import,Guava,public
From: https://www.cnblogs.com/Guhongying/p/18535300

相关文章

  • NOIP2024 前集训:多校A层冲刺NOIP2024模拟赛19
    前言这次不是之前学长吃完吐出来的shi,这次是新拉的热乎的烫嘴的shi。T1、2、3、4大样例全部错一遍,T1题面和时限再错一遍哈哈哈。T4假做法有60哈哈哈,大样例跑出来半个对的都没有能得60哈哈哈。accodersT1前半小时没数据做得快的全部都死哈哈(还好我第一份被卡常了后......
  • 【Linux】获得同一子网下当前在线设备IP/Latency/MAC 通过nmap指定CIDR扫描当前在线设
    【Linux】获得同一子网下当前在线设备IP/Latency/MAC通过nmap指定CIDR扫描当前在线设备通过路由器的后台,查看当前在线设备,受到网卡版本的影响,有时会有部分设备看不见MAC和分配的IP。此时,可以借助命令行工具扫描子网下所有连接的设备信息与通信状态。Nmap是一个强大的网......
  • APP压力测试3--Monkey Script命令
    MonkeyScript执行Monkey的脚本命令:adbshellmonkey-f<编写的脚本文件><执行次数>1、DispatchTrackball轨迹球事件轨迹球事件DispatchTrackball(longdowntime(按键最初被按下的时间),longeventide(事件发生的时间),intaction(具体操作了按下还是弹起),floatx(x的坐标点),flo......
  • javascript中的this
    在JavaScript中,this关键字的值取决于它被使用的上下文。它并不像其他编程语言中的this总是指向对象的实例,而是可能指向不同的对象。以下是几种常见的this的用法及其指向的内容:全局上下文在全局范围(即没有在任何函数或对象内)中,this指向全局对象。在浏览器中,这通常是window对象。......
  • 大模型--训练 加速之 流水线并行Pipeline Parallelism-10
    目录1.参考2.概述3.目标4.模型并行4.流水线并行4.1切分micro-batch4.2re-materialization(activecheckpoint)5.实验效果5.1GPU数量VS模型大小ofModelParameter表示模型的参数量5.2GPU数量VS训练速度5.3Gpipe下时间消耗分布1.参考https://zhuanlan.zhihu.com/p/6......
  • linux新增物理卷,扩容逻辑分区,出现WARNING: xfs signature detected on /dev/vdb at of
    linux新增物理卷出现WARNING:xfssignaturedetectedon/dev/vdbatoffset0.Wipeit?[y/n]:标识这个/dev/vdb磁盘已经从0位置被标记为xfs类型的文件系统报错解释:这条信息表示在设备/dev/vdb上检测到了XFS文件系统的签名。通常情况下,这可能意味着分区/dev/vdb已被......
  • 前端使用 jszip.js 和 FileSaver.js 下载并压缩文件
    asyncexport_data(){letzip=newJSZip()//下载文件并添加到ZIPfor(constiofthis.tableData){constdata=awaitfetch(i.path).then(response=>response.arrayBuffer())constimageByteStream=newUint8Array(data).subarray(1024)......
  • JavaScript中的解构赋值
    写在前面在JavaScript中,解构赋值是一种简洁而强大的语法特性,它允许我们从数组或对象中提取值并将其分配给变量。这个功能可以大大简化代码,提高可读性和可维护性。今天,我们将深入探讨解构赋值的用法和规则。数组解构赋值数组解构赋值允许我们从数组中提取值并将其分配给变......
  • [赛记] NOIP2024加赛1 && 多校A层冲刺NOIP2024模拟赛18
    暴力错解大赛玩游戏82pts乱糊的错解,正确性和时间复杂度都不对,但是拿了82pts;对于正解,考虑从$k$将原序列分成两个部分,左边和右边,然后分别求一次前缀和(注意这里,可以省去很多分讨和常数),设前一个前缀和数组为$a$,后一个为$b$,那么问题就转化成有两个指针$i,j$,可以任......
  • 洛谷题单指南-二叉堆与树状数组-P2827 [NOIP2016 提高组] 蚯蚓
    原题链接:https://www.luogu.com.cn/problem/P2827题意解读:初始n个数,每次取最大值x,根据u/v分成两部分:x*u/v,x-x*u/v,然后其余数都增加q,整个过程重复m次。输出有两类数据:第t,2t,3t...次取出的最大值;最后剩余的数第t,2t,3t...个,从大到小输出。解题思路:直观上,通过模拟法可以实......