tianyun 2 yıl önce
ebeveyn
işleme
8d6e2a68fc

+ 36 - 0
redis.lua

@@ -0,0 +1,36 @@
+--获取上次时间、剩余token
+local ratelimit_info = redis.pcall('HMGET', KEYS[1], 'last_time', 'current_token')
+local last_time = ratelimit_info[1]
+local current_token = tonumber(ratelimit_info[2])
+
+local max_token = tonumber(ARGV[1])
+local token_rate = tonumber(ARGV[2])
+local current_time = tonumber(ARGV[3])
+
+if current_token == nil then
+    current_token = max_token
+    last_time = current_time
+else
+    local past_time = current_time - last_time
+
+    --超过一秒,则添加令牌
+    if past_time > 1000 then
+        current_token = current_token + token_rate
+        last_time = current_time
+    end
+
+    --防止令牌超限
+    if current_token > max_token then
+        current_token = max_token
+        last_time = current_time
+    end
+end
+
+local result = 0
+if (current_token > 0) then
+    result = 1
+    current_token = current_token - 1
+    last_time = current_time
+end
+redis.call('HMSET', KEYS[1], 'last_time', last_time, 'current_token', current_token)
+return result

+ 10 - 2
springboot-main/src/main/java/com/alvin/Application.java

@@ -1,12 +1,20 @@
 package com.alvin;
 
 
-import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
 public class Application {
+
     public static void main(String[] args) throws Exception {
-        SpringApplication.run(Application.class);
+        //SpringApplication.run(Application.class);
+        for (int i = 0; i < 100; i++) {
+            boolean test = JedisUtil.tryAcquire("test213", 100, 2);
+            System.out.println("第" + i + "次操作" + (test ? "成功" : "失败"));
+            Thread.sleep(100);
+        }
+
     }
+
+
 }

+ 48 - 0
springboot-main/src/main/java/com/alvin/JedisUtil.java

@@ -0,0 +1,48 @@
+package com.alvin;
+
+
+import com.alvin.util.FileUtil;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+public class JedisUtil {
+    public static volatile JedisPool pool;
+    public static String luaStr = "";
+
+    static {
+        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
+        jedisPoolConfig.setMinIdle(4); // 初始化数
+        jedisPoolConfig.setMaxIdle(8); // 最大空闲数
+        jedisPoolConfig.setMaxTotal(10);  // 最大连接数
+        pool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379);
+        try {
+            luaStr = FileUtil.readToString("redis.lua");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 获取令牌
+     *
+     * @param key  请求id
+     * @param max  最大能同时承受多少的并发(桶容量)
+     * @param rate 每秒生成多少的令牌
+     * @return 获取令牌返回true,没有获取返回false
+     */
+    public static boolean tryAcquire(String key, int max, int rate) {
+        try (Jedis jedis = pool.getResource()) {
+            return Long.valueOf(1).equals(
+                    jedis.evalsha(jedis.scriptLoad(luaStr),
+                            Arrays.asList(key),
+                            Arrays.asList(Integer.toString(max), Integer.toString(rate), Long.toString(System.currentTimeMillis())))
+            );
+        }
+    }
+
+
+}