假設(shè)一個(gè)用戶(用IP判斷)每分鐘訪問(wèn)某一個(gè)服務(wù)接口的次數(shù)不能超過(guò)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: 進(jìn)行流量控制,允許訪問(wèn)返回true 不允許訪問(wèn)返回false * @param: @param key 放入redis的key,放入前要在key之前添加前綴 前綴配置在eds.properties中的 redis.prefix * @param: @param timeOut 超時(shí)時(shí)間單位秒 * @param: @param count 超時(shí)時(shí)間內(nèi)允許訪問(wèn)的次數(shù) * @param: @param type 不同類型的數(shù)據(jù) * @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:{},超出{}秒內(nèi)允許訪問(wèn){}次的限制,這是第{}次訪問(wèn)", 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:{},{}秒內(nèi)允許訪問(wèn){}次,第{}次訪問(wèn)", new Object[] { key, timeOut, count, newTimes }); } else { result = true; } } if (result) { logger.debug("key:{},訪問(wèn)次數(shù){}", new Object[] { key, newTimes }); } } catch (Exception e) { logger.error("流量控制發(fā)生異常", e); e.printStackTrace(); // 當(dāng)發(fā)生異常時(shí) 允許訪問(wèn) result = true; } finally { jedis.close(); } return result; } } ConfigurationUtil 為配置文件中的值 方法調(diào)用: // 限制器,限制在60秒之內(nèi)最多登錄5次 if (RateLimit.allow("RECOMMENDCODE",accountCode, 60, 5)) { //處理業(yè)務(wù) }else{ //返回失敗 } --------------------- 作者:猴德華 來(lái)源:CSDN 原文:https://blog.csdn.net/semengzhu/article/details/78459914 版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接! |
|