Redisson使用-springmvc

Redisson使用-springmvc

日前在学习redisson,记录一下。

配置

1.首先官网连接:https://github.com/redisson/redisson
2.我采用的是xml配置,一下是官网配置(哨兵模式,其他模式在官网wiki中可以看到):

<redisson:client
    id="redisson"
    name="redisson1,redisson2"
    threads="0"
    netty-threads="0"
    codec-ref="myCodec" 
    transport-mode="NIO"
    redisson-reference-enabled="true"
    codec-provider-ref="myCodecProvider"
    resolver-provider-ref="myResolverProvider"
    executor-ref="myExecutor"
    event-loop-group-ref="myEventLoopGroup"
>
    <!--
    这里的name属性和qualifier子元素不能同时使用。

    id和name的属性都可以被用来作为qualifier的备选值。
    -->
    <!--<qualifier value="redisson3"/>-->
    <redisson:sentinel-servers
        idle-connection-timeout="10000"
        ping-timeout="1000"
        connect-timeout="10000"
        timeout="3000"
        retry-attempts="3"
        retry-interval="1500"
        reconnection-timeout="3000"
        failed-attempts="3"
        password="do_not_use_if_it_is_not_set"
        subscriptions-per-connection="5"
        client-name="none"
        load-balancer-ref="myLoadBalancer"
        subscription-connection-minimum-idle-size="1"
        subscription-connection-pool-size="50"
        slave-connection-minimum-idle-size="10"
        slave-connection-pool-size="64"
        master-connection-minimum-idle-size="10"
        master-connection-pool-size="64"
        read-mode="SLAVE"
        subscription-mode="SLAVE"
        master-name="myMaster"
        database="0"
    >
        <redisson:sentinel-address value="redis://127.0.0.1:26379" />
        <redisson:sentinel-address value="redis://127.0.0.1:26380" />
    </redisson:sentinel-servers>
</redisson:client>

<!-- 最基本配置 -->
<redisson:client>
    <redisson:sentinel-servers master-name="myMaster">
        <redisson:sentinel-address value="redis://127.0.0.1:26379" />
        <redisson:sentinel-address value="redis://127.0.0.1:26380" />
        ....
    </redisson:sentinel-servers>
</redisson:client>

一下是我自己的配置和部分标注:

bean id="stringCodec" class="org.redisson.client.codec.StringCodec"></bean>
<redisson:client id="redissonClient" codec-ref="stringCodec">
    <redisson:sentinel-servers master-name="${redis.masterName}">
        <redisson:sentinel-address value="http://${redis.host1}" />
        <redisson:sentinel-address value="http://${redis.host2}" />
        <redisson:sentinel-address value="http://${redis.host3}" />
    </redisson:sentinel-servers>
</redisson:client>

<!--一下均摘抄自官网  
    master-name  主服务器名称
    readMode  读取操作的负载均衡模式 默认 从节点读取
    subscriptionMode  订阅操作的负载均衡模式默认 从节点读取
    loadBalancer(负载均衡算法类的选择) 默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer
    	org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法
        org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法
        org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法
    slaveConnectionMinimumIdleSize(从节点最小空闲连接数) 默认 32
    slaveConnectionPoolSize(从节点连接池大小)  默认 64
    masterConnectionMinimumIdleSize(主节点最小空闲连接数) 默认 32
    masterConnectionPoolSize(主节点连接池大小) 默认 64
    idleConnectionTimeout(连接空闲超时,单位:毫秒)  默认值:10000
    timeout(命令等待超时,单位:毫秒)   默认值:3000
    retryAttempts(命令失败重试次数) 默认值:3
    retryInterval(命令重试发送时间间隔,单位:毫秒  默认值:1500
    reconnectionTimeout(重新连接时间间隔,单位:毫秒) 默认值:3000
    failedAttempts(执行失败最大次数) 默认值:3
    database(数据库编号)默认值:0   尝试连接的数据库编号。
    password(密码)    默认值:null    用于节点身份验证的密码。
    subscriptionsPerConnection(单个连接最大订阅数量)  默认值:5   每个连接的最大订阅数量。
    clientName(客户端名称)   默认值:null    在Redis节点里显示的客户端名称。
    还有ssl的配置 待续
    -->

3.写一个工具类orTemplate类

@Service
public class RedissonTemplate implements InitializingBean {

    private static final Logger log = Logger.getLogger(RedissonTemplate.class);

    @Autowired
    RedissonClient redissonClient;

    private static Redisson redisson;

    private static final String LOCK_TITLE = "redisLock_";

    public static boolean acquireSecond(String lockName, Integer waitTime, Integer timeOutSecond){
        try {
            String key = LOCK_TITLE + lockName;
            RLock mylock = redisson.getLock(key);
            //lock提供带timeout参数,timeout结束强制解锁,防止死锁
            //先尝试在超时时间内获取锁,如果没有获取到,此时如果等待时间还有剩余进入循环不断取尝试获取锁 直到时间结束退出  循环中是订阅,时间结束取消订阅
            return mylock.tryLock(waitTime, timeOutSecond, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
           log.error(ExceptionFormatUtil.exception(e));
            if (SysConfig.send()) DingdingNewsPushUtils.send("获取redisson锁异常:" + ExceptionFormatUtil.exceptionDD(e));
        }
        return false;
    }

    public static boolean acquireMinuts(String lockName, Integer waitTime, Integer timeOutMinuts){
        return acquireSecond(lockName, waitTime, timeOutMinuts * 60);
    }

    public static void release(String lockName){
        String key = LOCK_TITLE + lockName;
        RLock mylock = redisson.getLock(key);
        mylock.unlock();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        redisson = (Redisson) redissonClient;
        log.info("[cos_redisson_config_info]" + redisson.getConfig().toJSON());
    }
}

4.自己错误记录:
a.第一次调用redisson时候,参考资料直接使用一下方式

private static RedissonClient redisson = Redisson.create();

这种方法是用代码加载配置的时候用的,如下所示:

Config config = new Config();
config.setCodec(param);
config.setExecutor(param);
private static RedissonClient redisson = Redisson.create(config);

5.循环方式
a.while循环,一次接着一次的尝试,这个方法的缺点是会造成大量无效的锁申请。
b.Thread.sleep,在上面的while方案中增加睡眠时间以降低锁申请次数,缺点是这个睡眠的时间设置比较难控制。
c.基于信息量,当锁被其它资源占用时,当前线程订阅锁的释放事件,一旦锁释放会发消息通知待等待的锁进行竞争,有效的解决了无效的锁申请情况。核心逻辑是this.getEntry(threadId).getLatch().tryAcquire,this.getEntry(threadId).getLatch()返回的是一个信号量,有兴趣可以再研究研究。

先记这么多 待续。。。。

猜你喜欢

转载自blog.csdn.net/weixin_43189126/article/details/85210565