redis分布式锁到redisson的转变

首先导入redis依赖:


     org.springframework.boot
     spring-boot-starter-data-redis

然后配置redis:

spring:
    redis:
        host: 192.168.1.210
        port: 6379

使用redis实现分布式主体代码:

@Autowired
StringRedisTemplate redisTemplate;

public String getDistributeResult() {
    //1.占分布式锁
    String uuid = UUID.randomUUID().toString();
    Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);//保证锁的赋值和过期时间设置的原子性,同时过期时间避免出现死锁问题
    if(lock){
        System.out.println("获取分布式锁成功。。。");
        //加锁成功...执行业务
        String result = "";
        try{
            result = getResult();
        }finally{
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            //删除锁
            Long lock1 = redisTemplate.execute(new DefaultRedisScript(script, Long.class), Arrays.asList("lock"), uuid);
        }

        return result;
    }else{
        try {
        	//休眠100ms重试
            Thread.sleep(200);
        } catch (InterruptedException e) {

        }
        return getDistributeResult();//自旋方式
    }
}

public String getResult(){
	return "ok";
}
lua脚本解锁(获取值并进行对比)也是为了避免客户端在过期时间后尝试释放锁,删除稍后获得锁的另一个客户端创建的,参考:SET | Redis

开发中经常会使用redisson代替上面繁琐的(容易遗漏的)分布式锁实现,大量节省了开发时间,让程序员把更多的精力放在业务开发上。

想要使用redisson首先要引入依赖(redis的也需要前面已经引入过了)


    org.redisson
    redisson
    3.12.0

创建redisson自定义配置类:

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
public class MyRedissonConfig {

    @Bean
    public RedissonClient redisson() throws IOException {
        //1.创建配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.1.210:6379");
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }
}

然后就可以使用redisson了,如下:

@Autowired
RedissonClient redisson;

public String getResultWithRedissonLock() {
    RLock lock = redisson.getLock("redisson-lock");
    lock.lock();

    String result = "";
    try{
        result = getResult();
    }finally{
        lock.unlock();
    }

    return result;
}

lock()加锁,unlock()释放锁,就是这么简单。

redisson的锁默认过期时间30s(LockWatchdogTimeout看门狗的默认时间),且支持自动续期(即业务执行未完成可以延长锁的过期时间),只要占锁成功,就会启动一个定时任务【重新给锁设置过期时间,新的过期时间就是看门狗的默认时间】,每隔10s(internalLockLeaseTime【看门狗时间】 / 3, 10s)都会自动再次续期,续成30s

如果我们设置了过期时间,那么就不会存在自动续期等操作,

lock.lock(10, TimeUnit.SECONDS);但是一定要保证自动解锁的时间要大于业务执行的时间。

同时redisson还支持多种锁机制,包含RReadWriteLock,RSemaphore,RCountDownLatch等

可以根据自己的业务场景使用不同的锁。

你可能感兴趣的:(java,分布式锁,redisson)