1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| package cn.inkroom.study.redis;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; import redis.clients.jedis.Response;
public class TimeLimit {
private Jedis jedis;
public TimeLimit() { jedis = new Jedis("192.168.3.64", 6379); }
public boolean allowExecute(String userId, String action, int period, int maxCount) {
String key = String.format("limit:%s:%s", userId, action); long now = System.currentTimeMillis(); Pipeline pipelined = jedis.pipelined(); pipelined.multi();
pipelined.zadd(key, now, now + ""); pipelined.zremrangeByScore(key, 0, now - period * 1000L); Response<Long> zcard = pipelined.zcard(key); pipelined.expire(key, (period) + 1); pipelined.exec(); pipelined.close();
return zcard.get() <= maxCount; }
public boolean allowExecuteIgnoreFail(String userId, String action, int period, int maxCount) { String key = String.format("limit:%s:%s", userId, action); long now = System.currentTimeMillis();
Long size = ((Long) jedis.eval( "redis.call('zremrangeByScore',KEYS[1],0,ARGV[1]);" + "local size=redis.call('zcard',KEYS[1]);" + "if (size < tonumber(ARGV[2])) then" + " redis.call('zadd',KEYS[1],tonumber(ARGV[3]),ARGV[3]);" + "end;" + "redis.call('expire',KEYS[1],tonumber(ARGV[4]));" + "return size" , 1, key, (now - period * 1000L) + "", maxCount + "", now + "", (period + 1) + "")); return size < maxCount;
}
public static void main(String[] args) { TimeLimit timeLimit = new TimeLimit();
int count = 2; for (int i = 0; i < 100; i++) { System.out.println(timeLimit.allowExecuteIgnoreFail("userId-", "action", 5, count)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }
}
}
|