zoukankan      html  css  js  c++  java
  • Redission 中 RPermitExpirableSemaphore 用法

     RPermitExpirableSemaphore是什么
    首先,RPermitExpirableSemaphore 是出自于Redisson,Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid),Redisson也是redis官方推荐的,比较常用的是它的分布式锁。
    Redisson中文文档:
    [https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95)
    RPermitExpirableSemaphore ,可过期性信号量
    接口文档:
    [https://www.javadoc.io/doc/org.redisson/redisson/latest/index.html](https://www.javadoc.io/doc/org.redisson/redisson/latest/index.html)

     用法
    举个栗子
    创建RedissonClient 单机版

    @Bean
    public RedissonClient redissonClient() {
    Config config = new Config();
    // 单机模式
    config.useSingleServer()
    .setAddress("redis://127.0.0.1:6379")
    ;
    return Redisson.create(config);
    }
    

      


    一次完整的获得许可,释放许可

    public void test() throws Exception {
    //通过redissonClient创造一个key为xxx的信号量
    RPermitExpirableSemaphore semaphore = redissonClient.getPermitExpirableSemaphore("xxx");
    //给信号量设置数量为5,用在限流中就是只允许5次请求
    while (!semaphore.trySetPermits(5)) ;
    
    //tryAcquire 的第一个参数是waittime,尝试获得许可证的最大等待时间,超过这个时间则返回null
    //第二个参数是许可证的过期时间,也是精华所在,即使发生宕机,jvm崩溃等情况,也不用担心,信号量过期会自动释放
    //成功之后会获得一个许可证ID,是在获取期间每次生成的128位唯一随机标识符
    String permitId = semaphore.tryAcquire(1, 5, TimeUnit.SECONDS);
    System.out.println(permitId);
    //释放许可证还需要之前获得permitId
    semaphore.release(permitId);
    }
    

      

    semaphore.trySetPermits() 中 lua脚本分析

    @Override
    public RFuture<Boolean> trySetPermitsAsync(int permits) {
    return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
    "local value = redis.call('get', KEYS[1]); " +
    //value==0或者false,都是代表没有这个信号量,进入创建信号量的逻辑
    "if (value == false or value == 0) then "
    //所谓创建,其实就是redis的set操作, ARGV[1]即为要设置的许可数
    + "redis.call('set', KEYS[1], ARGV[1]); "
    + "redis.call('publish', KEYS[2], ARGV[1]); "
    + "return 1;"
    + "end;"
    + "return 0;",
    Arrays.<Object>asList(getName(), getChannelName()), permits);
    }
    

      

     异常记录
    1.`Caused by: org.redisson.client.RedisException: ERR This instance has cluster support disabled. channel: [id: 0x0fd46049, L:/127.0.0.1:62555 - R:/127.0.0.1:6379] command: CommandData [promise=org.redisson.misc.RedissonPromise@74bd3426[Not completed], command=(CLUSTER NODES), params=[], codec=null]
    `
    是由于设置了集群

    ```
    Config config = new Config();
    // set集群版报错
    config.useClusterServers()
    .addNodeAddress("redis://127.0.0.1:6379")
    ```
    应该为

    ```
    config.useSingleServer()
    .setAddress("redis://127.0.0.1:6379")
    ```

    2.trySetPermits 一直返回的false,可以查看下是否redis中有了相同的key,trySetPermits 其实就是往redis中塞值。

    另外,浅蓝浅蓝777也是我的号。

  • 相关阅读:
    scikit-learn一般实例之四:使用管道和GridSearchCV选择降维
    scikit-learn一般实例之四:管道的使用:链接一个主成分分析和Logistic回归
    scikit-learn一般实例之三:连接多个特征提取方法
    scikit-learn一般实例之一:保序回归(Isotonic Regression)
    scikit-learn一般实例之一:绘制交叉验证预测
    weblogic控制台定制不同权限的用户
    jquery给input域赋值和取值
    键盘对应的ASCII码
    js控制键盘只能输入数字和退格键,delete键
    mysql创建用户及授权相关命令
  • 原文地址:https://www.cnblogs.com/number7/p/9594518.html
Copyright © 2011-2022 走看看