java 实现ip访问量控制_java 实现IP访问量控制

网站中发现有人恶意频繁的注册账号,打算在注册接口处增加效验工具,思路如下:

记录访问IP 和 时间

如果在五分钟内连续访问更新计时器更新计数器

10分钟内不访问计时器清零

思路很简单源码如下

package com.zcjy.mft.util;

import java.util.Date;

import org.apache.commons.collections.map.LRUMap;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class Forbidener {

final Log log = LogFactory

.getLog(Forbidener.class);

private Forbidener(){

ipmap = new LRUMap(100000);

}

public static Forbidener forbidener;

public static Forbidener getInstance(){

if(forbidener == null){

forbidener = new Forbidener();

}

return forbidener;

}

LRUMap ipmap = null ;

/**

* 超过次数封禁

*/

long maxTime = 10;

/**

* 超过访问时间重新计时

*/

long minInteval = 60*1000*60*4;

/**

* 封禁的时间

*/

long forbidenTime = 60*1000*60*4;

public int getMapSize() {

return ipmap.size();

}

public void setMaxTime(int i) {

maxTime = i;

}

public void setMinInteval(int i) {

minInteval = i;

}

public void setForbidenTime(int i) {

forbidenTime = i;

}

public void setMaxMapSize(int i) {

ipmap = new LRUMap(i);

}

public boolean check(String IP){

IPer iper = (IPer)ipmap.get(IP);

if(iper == null){

iper = new IPer();

iper.lastVisiterTime = new Date();

iper.visitTimes = 1;

ipmap.put(IP, iper);

return true;

}

Date now = new Date();

if(iper.isForbiden){

if(now.getTime() - iper.lastVisiterTime.getTime() > forbidenTime){

//解封

iper.isForbiden = false;

iper.visitTimes = 1;

iper.lastVisiterTime = now;

log.debug("unforbiden ip:" + IP);

return true;

}else{

return false;

}

}

if(now.getTime() - iper.lastVisiterTime.getTime() > minInteval){

//太久没有访问了,重新计时

iper.lastVisiterTime = now;

iper.visitTimes = 1;

iper.isForbiden = false;

log.debug("reset ip:" + IP);

return true;

}else{

iper.lastVisiterTime = now;

iper.visitTimes = iper.visitTimes +1;

if(iper.visitTimes > maxTime){

//封禁

iper.isForbiden = true;

log.debug("forbiden ip:" + IP);

return false;

}else{

return true;

}

}

}

public static void main(String[] args) throws InterruptedException {

Date d1 = new Date();

Thread.sleep(1000);

Date d2 = new Date();

System.out.println(d1.getTime() - d2.getTime());

}

}

class IPer {

Date lastVisiterTime ;

int visitTimes;

boolean isForbiden = false;

}测试代码如下

package com.zcjy.mft.util;

import org.junit.AfterClass;

import org.junit.Assert;

import org.junit.Test;

import com.zcjy.mft.util.Forbidener;

public class TestForbidener {

public static void setup(){

//构造初始化数据

}

@AfterClass

public static void clear(){

}

/**

* @throws InterruptedException

*/

@Test

public void check() throws InterruptedException{

//测试十次封禁

Forbidener fb = Forbidener.getInstance();

fb.setMaxTime(10);

fb.setMinInteval(10*1000);

fb.setForbidenTime(60*1000);

fb.setMaxMapSize(3);

String testIP = "127.0.0.1";

for(int i = 1 ; i <= 10;i++){

System.out.println("check");

Assert.assertTrue(fb.check(testIP));

Thread.sleep(1000);

}

Assert.assertFalse(fb.check(testIP));

//测试解封

System.out.println("sleep more than 1 min");

Thread.sleep(65*1000);

Assert.assertTrue(fb.check(testIP));

//测试最短周期

for(int i = 1;i<= 9 ;i++){

Assert.assertTrue(fb.check(testIP));

System.out.println("check");

Thread.sleep(1000);

}

System.out.println("sleep more than 10 sec");

Thread.sleep(15*1000);

Assert.assertTrue(fb.check(testIP));

//测试淘汰

fb.check("1");

fb.check("2");

Assert.assertTrue(fb.getMapSize() == 3);

fb.check("3");

Assert.assertTrue(fb.getMapSize() == 3);

//

}

} 不写测试用例的程序员不是好程序员;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值