Java 中的挪用逻辑:
- --lua 下标从 1 开始
- -- 限流 key
- local key = KEYS[1]
- -- 限流巨细
- local limit = tonumber(ARGV[1])
- -- 获取当前流量巨细
- local curentLimit = tonumber(redis.call('get', key) or "0")
- if curentLimit + 1 > limit then
- -- 到达限流巨细 返回
- return 0;
- else
- -- 没有到达阈值 value + 1
- redis.call("INCRBY", key, 1)
- redis.call("EXPIRE", key, 2)
- return curentLimit + 1
- end
以是只必要在必要限流的处所挪用该要领对返回值举办判定即可到达限流的目标。
虽然这只是操作 Redis 做了一个粗暴的计数器,假如想实现相同于上文中的令牌桶算法可以基于 Lua 自行实现。
Builder 构建器
在计划这个组件时想只管的提供应行使者清楚、可读性、不易堕落的 API。
好比第一步,怎样构建一个限流工具。
最常用的方法天然就是结构函数,假若有多个域则可以回收重叠结构器的方法:
- public A(){}
- public A(int a){}
- public A(int a,int b){}
弱点也是显而易见的:假如参数过多会导致难以阅读,乃至假如参数范例同等的环境下客户端颠倒了次序,但不会引起告诫从而呈现难以猜测的功效。
第二种方案可以回收 JavaBean 模式,操作 setter 要领举办构建:
- A a = new A();
- a.setA(a);
- a.setB(b);
这种方法清楚易读,但却轻易让工具处于纷歧致的状态,使工具处于线程不安详的状态。
以是这里回收了第三种建设工具的方法,构建器:
- public class RedisLimit {
- private JedisCommands jedis;
- private int limit = 200;
- private static final int FAIL_CODE = 0;
- /**
- * lua script
- */
- private String script;
- private RedisLimit(Builder builder) {
- this.limit = builder.limit ;
- this.jedis = builder.jedis ;
- buildScript();
- }
- /**
- * limit traffic
- * @return if true
- */
- public boolean limit() {
- String key = String.valueOf(System.currentTimeMillis() / 1000);
- Object result = null;
- if (jedis instanceof Jedis) {
- result = ((Jedis) this.jedis).eval(script, Collections.singletonList(key), Collections.singletonList(String.valueOf(limit)));
- } else if (jedis instanceof JedisCluster) {
- result = ((JedisCluster) this.jedis).eval(script, Collections.singletonList(key), Collections.singletonList(String.valueOf(limit)));
- } else {
- //throw new RuntimeException("instance is error") ;
- return false;
- }
- if (FAIL_CODE != (Long) result) {
- return true;
- } else {
- return false;
- }
- }
- /**
- * read lua script
- */
- private void buildScript() {
- script = ScriptUtil.getScript("limit.lua");
- }
- /**
- * the builder
- * @param <T>
- */
- public static class Builder<T extends JedisCommands>{
- private T jedis = null ;
- private int limit = 200;
- public Builder(T jedis){
- this.jedis = jedis ;
- }
- public Builder limit(int limit){
- this.limit = limit ;
- return this;
- }
- public RedisLimit build(){
- return new RedisLimit(this) ;
- }
- }
- }
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|