使用redis进行用户接口访问时间次数限制

https://blog.csdn.net/semengzhu/article/details/78459914

假设一个用户(用IP判断)每分钟访问某一个服务接口的次数不能超过10次


import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;


/**
 * 
 * <p>Title:</p>
 */
public class RateLimit {



private static final Logger logger = LogUtil.get();

private static final String RATE_LIMIT = "RATELIMIT";

/** 
     * @Title: allow @Description: 进行流量控制,允许访问返回true 不允许访问返回false  
     * @param: @param key 放入redis的key,放入前要在key之前添加前缀 前缀配置在eds.properties中的 redis.prefix 
     * @param: @param timeOut 超时时间单位秒 
     * @param: @param count 超时时间内允许访问的次数 
     * @param: @param type 不同类型的数据
     * @param: @return 
     * @param: @throws 
     *             Exception @return: boolean @throws 
     */  
    public static boolean allow(String type,String key, int timeOut, int count) {  
  
//        Boolean useFc = Boolean.valueOf(EdsPropertiesUtil.getInstance().getProperty("flowControl.use"));  
//        // 若不使用流量控制直接返回true  
//        if (!useFc) {  
//            return true;  
//        }  
  
        boolean result = false;  
        Jedis jedis = null;  
        StringBuffer keyBuff = new StringBuffer(RATE_LIMIT);
        keyBuff.append("_").append(type).append(":").append(key);
        key = keyBuff.toString();
        try {  
        jedis = new Jedis(ConfigurationUtil.getRedisHost(), Integer.valueOf(ConfigurationUtil.getRedisPort()));
    if (StringUtils.isNoneEmpty(ConfigurationUtil.getRedisPassWord())) {
    jedis.auth(ConfigurationUtil.getRedisPassWord());
    }
    jedis.connect();
            Long newTimes = null;  
            Long pttl = jedis.pttl(key);  
  
            if (pttl > 0) {  
                newTimes = jedis.incr(key);  
                if (newTimes > count) {  
                    logger.info("key:{},超出{}秒内允许访问{}次的限制,这是第{}次访问", new Object[] { key, timeOut, count, newTimes });  
                } else {  
                    result = true;  
                }  
            } else if (pttl == -1 || pttl == -2 || pttl == 0) {  
  
                Transaction tx = jedis.multi();  
                Response<Long> rsp1 = tx.incr(key);  
                tx.expire(key, timeOut);  
                tx.exec();  
                newTimes = rsp1.get();  
                if (newTimes > count) {  
                    logger.info("key:{},{}秒内允许访问{}次,第{}次访问", new Object[] { key, timeOut, count, newTimes });  
                } else {  
  
                    result = true;  
                }  
  
            }  
            if (result) {  
                logger.debug("key:{},访问次数{}", new Object[] { key, newTimes });  
            }  
  
        } catch (Exception e) {  
            logger.error("流量控制发生异常", e);  
            e.printStackTrace();  
            // 当发生异常时 允许访问  
            result = true;  
        } finally {  
            jedis.close();  
        }  
  
        return result;  
  
    }  
}

ConfigurationUtil 为配置文件中的值

方法调用:

// 限制器,限制在60秒之内最多登录5次

if (RateLimit.allow("RECOMMENDCODE",accountCode, 60, 5)) {
             //处理业务
        }else{
   //返回失败
       }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值