java redis expire 1_运用redis键的expire时间,控制1一分钟内的访问量

通过Java利用Redis的expire功能,限制每分钟的最大访问次数以减轻网站压力。实现了一个Redis工具类,包含设置键值、判断键是否存在、自增1等方法,并在filter拦截器中检查访问权限。
摘要由CSDN通过智能技术生成

客户端频繁的访问网站,会对网站资源造成很大的压力,所以,需要限制时间段内的访问次数,如果访问过于频繁,应该禁止访问,采用redis实现这一需要,redis中,可以使用expire设置key的生存时间,这一特性很好的满足我们的需求,解决代码如下:

工具类:

package cn.sniper.tjfxpt.utils;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPool;

import redis.clients.jedis.JedisPoolConfig;

import redis.clients.jedis.exceptions.JedisDataException;

public class RedisUtil {

private static JedisPool jedisPool;

//每分钟允许最大访问次数

private static int MAX_ALLOWED_TIMES = 60;

static {

String host = "192.168.31.231";

int port = 6379;

JedisPoolConfig poolConfig = new JedisPoolConfig();

poolConfig.setMaxIdle(100);

poolConfig.setMaxTotal(500);

poolConfig.setMaxWaitMillis(20000);

poolConfig.setTestOnBorrow(true);

jedisPool = new JedisPool(poolConfig, host, port);

}

/**

* 如果key不存在,设置值,如果key存在,覆盖值

* @param key

* @param value

*/

public static void set(String key, String value) {

Jedis jedis = jedisPool.getResource();

jedis.set(key, value);

//用完后放回连接池

jedisPool.returnResourceObject(jedis);

}

/**

* 如果key不存在,设置值,如果key存在,不做任何操作

* @param key

* @param value

*/

public static void setIfNotExists(String key, String value) {

Jedis jedis = jedisPool.getResource();

jedis.setnx(key, value);

//用完后放回连接池

jedisPool.returnResourceObject(jedis);

}

/**

* 自加1

* @param key

* @param value

*/

public static void incrByOne(String key) {

Jedis jedis = jedisPool.getResource();

try {

//如果key对应的值不是数值型,会报异常

jedis.incr(key);

} catch(JedisDataException e) {

e.printStackTrace();

}

//用完后放回连接池

jedisPool.returnResourceObject(jedis);

}

/**

* 判断键是否存在

* @param key

* @return

*/

public static boolean exists(String key) {

Jedis jedis = jedisPool.getResource();

return jedis.exists(key);

}

/**

* 是否允许访问

* @param key

* @return

*/

public static boolean ifAllowed(String key) {

boolean flag = true;

Jedis jedis = jedisPool.getResource();

if(exists(key)) {

//key对应的value自加1

jedis.incr(key);

//取得key对应的value

String value = jedis.get(key);

try {

//如果在60秒的生存周期内的访问次数大于MAX_ALLOWED_TIMES,则不允许访问

if(Integer.parseInt(value) > MAX_ALLOWED_TIMES) {

flag = false;

}

} catch(RuntimeException e) {

e.printStackTrace();

}

} else {

//第一次访问,设置初始值1

jedis.set(key, "1");

//设置生存时间60秒

jedis.expire(key, 60);

}

//用完记得放回,否则池很快就用完

jedisPool.returnResourceObject(jedis);

return flag;

}

public static void main(String[] args) {

//setIfNotExists("sniper", "ccc");

//set("sniper", "ccc");

//incrByOne("sniper");

//System.out.println(exists("sniper"));

for(int i=0; i<70; i++) {

System.out.println(i + "" + ifAllowed("sniper"));

}

}

}

filter拦截器:

package cn.sniper.webkit.filter;

import java.io.IOException;

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.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import cn.sniper.tjfxpt.utils.RedisUtil;

public class SecureFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

}

@Override

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

boolean ifAllowed = true;

try {

HttpServletRequest req = (HttpServletRequest)request;

HttpServletResponse resp = (HttpServletResponse)response;

String uri = req.getRequestURI();

//ip地址

String ip = "";

if (req.getHeader("x-forwarded-for") == null) {

ip = req.getRemoteAddr();

} else {

ip = req.getHeader("x-forwarded-for");

}

ip = "0:0:0:0:0:0:0:1".equals(ip)?"127.0.0.1":ip;

String key = ip + "-" + uri;

ifAllowed = RedisUtil.ifAllowed(key);

if(!ifAllowed) {

req.getSession().invalidate();

resp.sendRedirect(req.getContextPath() + "/gotoError.xhtml");

} else {

chain.doFilter(request, response);

}

//防止因为redis异常导致服务不可用

} catch(Throwable e) {

chain.doFilter(request, response);

}

}

@Override

public void destroy() {

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值