`
eimhee
  • 浏览: 2152875 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java 实现IP访问量控制

阅读更多

同一个IP 访问网站, 不能同时超过配置的最大值, 可以用来保护REST IP 或者DOS攻击

 

/*
 * Pprun's Public Domain.
 */
package org.pprun.common.security;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.scheduling.annotation.Scheduled;

/**
 * A filter to throttle only a limited number of requests from the same ip per second.
 * <p>
 * Two parameters need to inject:
 * <ol>
 * <li>common.throttle.maxConcurrentRequests=10</li>
 * <li>common.throttle.period=1000</li>
 * </ol>
 * <br />
 * If you use {@literal Spring} for {@lit DI}, it can be done as below in application {@literal web.xml}:
 * <br />
 * {@code 
 *      <filter>  
 *          <description>A filter to throttle only a limited number of requests from the same ip per second.</description>  
 *          <filter-name>throttleFilter</filter-name>  
 *          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
 *      </filter>
 * }
 * <br />
 * And a bean with {@code id="throttleFilter"} should be defined in {@literal application.xml}.
 * </p>
 * @author <a href="mailto:pizhigang@letv.com">pizhigang</a>
 */
//@Component
public class ThrottleFilter implements Filter, ThrottleFilterMXBean {

    private static Logger log = LoggerFactory.getLogger(ThrottleFilter.class);
    // map(ip, requestCount)
    private Map<String, Integer> ip2countCache = new HashMap<String, Integer>();
    private Set<String> blackList = new HashSet<String>();
    private int maxConcurrentRequests;
    private static final long PERIOD = 1L; // second
    private boolean enable = false;

    @Override
    public void init(FilterConfig config) throws ServletException {
        // nothing
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain nextFilter) throws ServletException, IOException {
        if (enable) {
            final String ip = request.getRemoteAddr();
            boolean isOverflow;

            synchronized (this) {
                Integer count = ip2countCache.get(ip);

                if (count == null || count.intValue() == 0) {
                    count = 0;
                }

                if (count < maxConcurrentRequests) {
                    isOverflow = false;
                    ip2countCache.put(ip, count + 1);
                } else {
                    isOverflow = true;
                    blackList.add(ip);
                }
            }

            if (isOverflow) {
                // block it
                log.info(" ip {} has reached the threshold {} in {} second, block it!", new Object[]{ip, maxConcurrentRequests, PERIOD});

                if (response instanceof HttpServletResponse) {
                    ((HttpServletResponse) response).sendError(503, ip + " has too many concurrent requests per " + PERIOD + " second");
                }
                return;
            }
        } // else go ahead below

        // every thing is okay, go ahead
        nextFilter.doFilter(request, response);
    }

    // every 1 second
    @Scheduled(fixedRate = PERIOD * 1000)
    public void throttlingJob() {
        if (enable) {
            log.debug("Throttle Filter clean up job is running");
            synchronized (ThrottleFilter.this) {
                for (Map.Entry<String, Integer> ip2count : ip2countCache.entrySet()) {
                    Integer count = ip2count.getValue();
                    String ip = ip2count.getKey();

                    if (count == null || count <= 1) {
                        ip2countCache.remove(ip);
                    } else {
                        if (count == maxConcurrentRequests) {
                            // remove from blacklist
                            log.info("Throttle Filter: removing {} from black list", ip);
                            blackList.remove(ip);
                        }

                        ip2countCache.put(ip, count - 1);
                    }
                }
            }
            log.debug("Throttle Filter clean up job is done");
        }
    }

    /**
     * Any cleanup for the filter.
     */
    @Override
    public void destroy() {
        log.warn("destorying Throttle Filter");
    }

    /**
     * Sets the maximum number of concurrent requests for a single IP.
     */
    @Required
    public void setMaxConcurrentRequests(int max) {
        maxConcurrentRequests = max;
    }

    @ManagedAttribute(description = "is the throttle filter enable or not")
    @Override
    public boolean isEnable() {
        return enable;
    }

    @Required
    @Override
    public void setEnable(boolean enable) {
        log.info("set enable to {}", enable);
        if (enable == false) {
            log.info("Throttle filter will be disabled");
        }

        this.enable = enable;
    }

    public Set<String> getBlackList() {
        // for exactly, it might need synchronized, but no hurt for snapshoot in one or severl seconds
        return Collections.unmodifiableSet(blackList);
    }
}

 

0
2
分享到:
评论

相关推荐

    java ip匹配 访问量+1

    java ip匹配 访问量+1 从 `IP地址文件` 中读取地址关系到自己的数据结构中; 2. 从 `日志文件` 中读取ip,解析关联的城市,对应的城市访问量 `+1` ; 3. 统计访问量最多的前10城市

    JAVA 统计网站的访问量PV,UV

    在IT行业中,统计网站的访问量是...总之,通过Java、Spring和MySQL的结合,我们可以构建一个有效的访问量统计系统,为网站运营提供关键的数据支持。同时,还需要注意隐私保护和数据安全,遵守相关的法规和最佳实践。

    Java获取ip所在地区

    在IT行业中,网络编程是不可或缺的一部分,而与之相关的任务之一就是识别和处理IP...正确理解和实现这一过程,可以帮助我们在各种应用场景下,如网站访问统计、网络安全分析等,更好地处理与IP地址相关的地理位置信息。

    java基于xml实现网站访问量统计

    Java基于XML实现网站访问量统计是一种常见的Web应用监控方法,主要通过解析XML文件来记录和分析网站的访问数据。在不改动数据库的情况下,这种技术提供了一种轻量级且易于集成的解决方案。以下是对这个主题的详细...

    java 动态换ip限制 ip频繁限制

    在互联网应用中,为了防止恶意爬虫或者滥用服务,很多网站和服务器会实施IP限制策略,尤其是对于频繁访问的行为。在这种背景下,Java开发者可能需要处理“动态换IP限制 IP频繁限制”的问题。本文将深入探讨如何在...

    Java采集最新动态代理IP

    本文将深入探讨如何使用Java结合Jsoup库来实现代理IP的爬取,以突破IP访问限制,实现动态IP代理。 首先,让我们了解什么是Java爬虫。Java爬虫是使用Java语言编写的一种程序,它能够自动地遍历互联网上的网页,抓取...

    java实现根据ip地址获取地理位置

    在Java编程中,根据IP地址获取地理位置是一项常见的需求,尤其在大数据分析、用户行为追踪或者安全防护等场景中。本文将介绍如何利用新浪和淘宝的API接口来实现这一功能。 首先,我们来看新浪的接口实现。新浪提供...

    网站统计在线人数,当前年、月、日访问量JAVA代码

    本主题将详细介绍如何使用Java编程语言来实现这一功能,特别是关注当前年、月、日的访问量统计。 首先,我们需要理解基本的统计原理。网站访问量通常通过记录每个独立访客的请求来计算。在线人数则是指在特定时间...

    java开发-IP解析方案-最新GeoIP2与IP2LOCATIO与dbIP离线数据库文件

    Java开发者可以使用IP2Location的Java SDK,通过简单的API调用来访问这些数据库,实现IP到地理位置的转换。IP2Location还提供了IP段归属、ISP信息等增值服务。 再者,dbIP是另一个开源的IP地理位置数据库,它提供了...

    ip查询库java版(含IP地址库)

    标题中的“ip查询库java版(含IP地址库)”指的是一个Java实现的IP查询库,它包含了一个IP地址数据库,可以用于根据输入的IP地址获取对应国家、地区和详细地址等信息。这样的库在Web应用、网络安全分析或者网络日志...

    java解析IP库获取对应中文省市及运营商(IP数据截止2014年10月)

    在Java中解析这个库,主要是为了实现IP地址到地理位置信息的快速查询,这在诸如网站访问统计、网络安全分析、广告定向投放等领域都有广泛的应用。 1. **解析IP库**:首先,我们需要将纯真IP库的文本文件加载到内存...

    ip2location.jar_java解析架包.rar

    在实际应用中,例如,如果你正在开发一个网站或者服务器应用,需要识别访问者来自哪里,或者需要根据用户IP地址提供本地化服务,那么这个IP2Location Java Component就能派上用场。你可以通过输入IP地址调用API,...

    用IP统计网站流量(java)

    在IT行业中,对网站流量进行统计是至关重要的...总的来说,Java提供了丰富的工具和技术来实现网站流量统计,包括Servlet、数据库操作、并发控制等。理解并掌握这些技术对于构建高效、可靠的网站流量统计系统至关重要。

    java 大文件ip 统计

    "Java大文件IP统计"这个主题就涉及到如何使用Java有效地处理大文件,特别是那些包含大量IP地址的文件,进行统计分析。在这个场景下,我们可能需要计算不同IP地址的数量,找出最频繁出现的IP,或者按某种顺序排列IP等...

    java禁止直接url访问图片

    例如,可以设置访问控制指令,仅允许特定IP或用户访问特定资源。 3. **Java Servlet**: 在Java环境下,我们可以利用Servlet来处理HTTP请求。Servlet是Java编写的小型服务器端程序,可以拦截并处理特定的HTTP请求...

    java读取纯真ip数据库

    标题中的“java读取纯真ip数据库”指的是使用Java编程语言来访问和处理纯真IP数据库。纯真IP数据库是中国互联网上广泛使用的IP地址库,它包含了大量的IP地址信息,如IP段、地理位置、网络运营商等数据,常用于IP地址...

    Java实现简单whois查询

    这个主题“Java实现简单whois查询”涉及到利用Java编程语言编写程序来执行这项任务。下面将详细介绍如何通过Java来实现Whois查询,并探讨相关的知识点。 首先,`WhoisBean.java`文件很可能包含了表示Whois查询结果...

    java源码包---java 源码 大量 实例

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    java远程控制器

    【Java远程控制器】是一种利用Java编程语言实现的远程桌面控制工具,它允许用户通过网络连接对另一台计算机进行操作。这个软件包含客户端和服务器两部分,由源代码和打包后的可执行程序组成,确保了用户可以理解并...

Global site tag (gtag.js) - Google Analytics