评论

收藏

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

数据库 数据库 发布于:2021-12-17 17:55 | 阅读数:349 | 评论:0

使用redis进行用户接口访问时间次数限制
假设一个用户(用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{
   //返回失败
     }









关注下面的标签,发现更多相似文章