博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis 漏桶算法—Lua
阅读量:4037 次
发布时间:2019-05-24

本文共 4170 字,大约阅读时间需要 13 分钟。

 

漏桶算法

import java.io.IOException;import java.nio.charset.Charset;import org.springframework.core.io.ClassPathResource;import com.google.common.io.Files;import redis.clients.jedis.Jedis;/*** *@author dzb *@date 2019/11/3 22:09 *@Description: 获取令牌 * */public class JedisGetRateLimiter {    private static final String IP = "192.168.0.163";    private String luaScript;    private String key;    public JedisGetRateLimiter(String scriptFile, String key) {        super();        this.key = key;        try {            luaScript = Files.asCharSource(new ClassPathResource(scriptFile).getFile(), Charset.defaultCharset())                    .read();        } catch (IOException e) {            e.printStackTrace();        }    }    public boolean acquire() {        try (Jedis jedis = new Jedis(IP, 6379)) {            return (Long) jedis.eval(luaScript, 1, key) == 1L;        }    }}import java.io.IOException;import java.nio.charset.Charset;import java.util.Timer;import java.util.TimerTask;import java.util.concurrent.TimeUnit;import org.springframework.core.io.ClassPathResource;import com.google.common.io.Files;import redis.clients.jedis.Jedis;/*** *@author dzb *@date 2019/11/3 22:09 *@Description: 初始化令牌 * */public class JedisInitRateLimiter implements AutoCloseable {    private static final String IP = "192.168.0.163";    private String luaScript;    private Timer timer;    private final Jedis jedis = new Jedis(IP, 6379);    public JedisInitRateLimiter(String scriptFile, String key, String limit) {        super();        try {            luaScript = Files.asCharSource(new ClassPathResource(scriptFile).getFile(), Charset.defaultCharset())                    .read();        } catch (IOException e) {            e.printStackTrace();        }        timer = new Timer();        // 放入令牌的时间间隔        long period = 1000L / Long.valueOf(limit);        // 通过定时器,定时放入令牌        timer.scheduleAtFixedRate(new TimerTask() {            @Override            public void run() {                System.out.println(                        System.currentTimeMillis() + " 放入令牌:" + ((Long) jedis.eval(luaScript, 1, key, limit) == 1L));            }        }, period, period);    }    @Override    public void close() throws Exception {        this.jedis.close();        this.timer.cancel();    }    public static void main(String[] args) throws Exception {        JedisInitRateLimiter jrls = new JedisInitRateLimiter("initRateLimit.lua", "test1", "5");        TimeUnit.SECONDS.sleep(10L);        jrls.close();    }}

Lua脚本

--令牌桶初始化操作  initRateLimit.lualocal key = KEYS[1] 			--限流KEYlocal limit = tonumber(ARGV[1]) --容量-- 获取当前令牌数local current = tonumber(redis.call('get', key) or "0")if current + 1 > limit then --如果超出容量    return 0else	redis.call("INCRBY", key, "1") --令牌数+1endreturn 1  --返回1代表不限流--取令牌  getRateLimit.lualocal key = KEYS[1] 			--限流KEY-- 获取当前可用令牌数local current = tonumber(redis.call('get', key) or "0")if current <= 0 then --没有令牌了    return 0else	redis.call("DECRBY", key, "1") --令牌数-1endreturn 1  --返回1代表不限流

测试类

//Controller层测试类	//初始化给入的容器数量	JedisInitRateLimiter initRateLimiter = new JedisInitRateLimiter("initRateLimit.lua","test","5");	JedisGetRateLimiter jtwl = new JedisGetRateLimiter("getRateLimit.lua","test");	public String doQuery2(String name) throws Exception {		// 从redis 上获得 自增后的值		if (!jtwl.acquire()) {			return System.currentTimeMillis() / 1000 + "秒杀结束,谢谢参与!";		}		return System.currentTimeMillis() / 1000 + "恭喜,秒杀成功!";	}//漏桶算法	 @Test	public void smoothRequestTest() throws Exception {		CountDownLatch cdl = new CountDownLatch(10);		CyclicBarrier cyb = new CyclicBarrier(10);		for (int i = 0; i < 10; i++) {			new Thread(() -> {				try {					cyb.await();				} catch (InterruptedException | BrokenBarrierException e) {					e.printStackTrace();				}				try {					System.out.println(Thread.currentThread().getName() + " " + orderc.doQuery2("test"));				} catch (Exception e) {					e.printStackTrace();				}				cdl.countDown();			}).start();		}		try {			cdl.await();		} catch (InterruptedException e) {			e.printStackTrace();		}		TimeUnit.SECONDS.sleep(1);		System.out.println(Thread.currentThread().getName() + " " + orderc.doQuery2("Mike"));	}

测试结果:

 

 

 

 

转载地址:http://iujdi.baihongyu.com/

你可能感兴趣的文章
UrlRewriteFilter使用说明
查看>>
java对redis的基本操作
查看>>
Java Math的 floor,round和ceil的使用
查看>>
通过url方式传递中文乱码解决办法
查看>>
Java的初始化机制、垃圾回收机制和内存分配机制
查看>>
MySQL5.6安装步骤(windows7/8_64位)
查看>>
FreeMarker基础配置
查看>>
Java中使用Jedis操作Redis
查看>>
Redis中常用命令
查看>>
spring下载
查看>>
读取request流
查看>>
微信消息模板的配置
查看>>
Spring框架结合Quartz实现任务调度实例
查看>>
Quartz Cron表达式 在线生成器
查看>>
struts2中action接收参数的3种方法
查看>>
java获取随机数
查看>>
url中传递中文参数时的转码与解码
查看>>
百度Ueditor设置允许上传的图片格式及大小
查看>>
java图形验证码生成工具类及web页面校验验证码
查看>>
微信菜单的配置
查看>>