文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何使用Redisson实现分布式锁?

2024-11-30 02:38

关注

在分布式系统中,当多个线程(或进程)同时操作同一个资源时,为了保证数据一致性问题,所以就需要一种机制来确保在同一时间只有一个线程(或进程)能够对资源进行修改,这就是分布式锁的作用。

分布式锁是一种在分布式环境下的锁实现,它允许在多个进程或服务器之间协调对共享资源的访问或操作。分布式锁的关键特性是它能够在集群内的不同节点间保持其锁定状态,使得某一时刻仅有一个客户端能够获取并持有该锁,从而确保对公共资源的原子性和一致性访问。

实现分布式锁的方式有多种,例如基于数据库、Redis、ZooKeeper 等中间件来实现,它们通常依赖于这些中间件提供的事务特性,或者命令语义来达到分布式环境下的锁效果。例如,Redis 通过 SETNX 命令配合过期时间可实现一个简单的分布式锁方案。

1、SETNX 存在的问题

虽然可以使用 SETNX 命令方便的实现分布式锁,但是 SETNX 存在以下问题:

那么如何解决以上这些问题呢?这就是今天要讲的重点 Redisson,使用 Redisson 框架就可以解决以上这些问题了

2、什么是 Redisson?

Redisson 是一个开源的用于操作 Redis 的 Java 框架。与 Jedis 和 Lettuce 等轻量级的 Redis 框架不同,它提供了更高级且功能丰富的 Redis 客户端。它提供了许多简化 Redis 操作的高级 API,并支持分布式对象、分布式锁、分布式集合等特性。

Redisson 官网:https://redisson.org/

3、Redisson 特性说明

4、Redisson 使用分布式锁

(1)添加 Redisson 框架支持

如果是 Spring Boot 项目,直接添加 Redisson 为 Spring Boot 写的如下依赖:




  org.redisson
  redisson-spring-boot-starter
  3.25.2 

其他项目,访问 https://mvnrepository.com/search?q=Redisson 获取具体依赖配置。

(2)配置 RedissonClient 对象

将 RedissonClient 重写,存放到 IoC 容器,并且配置连接的 Redis 服务器信息。

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;
@Configuration
public class RedissonConfig {
    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        // 也可以将 redis 配置信息保存到配置文件
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        return Redisson.create(config);
    }
}

(3)创建分布式锁

Redisson 分布式锁的操作和 Java 中的 ReentrantLock(可重入锁)的操作很像,都是先使用 tryLock 尝试获取(非公平)锁,最后再通过 unlock 释放锁,具体实现如下:

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
public class LockController {
    @Autowired
    private RedissonClient redissonClient;
    @GetMapping("/lock")
    public String lockResource() throws InterruptedException {
        String lockKey = "myLock";
        // 获取 RLock 对象
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 尝试获取锁(尝试加锁)(锁超时时间是 30 秒)
            boolean isLocked = lock.tryLock(30, TimeUnit.SECONDS);
            if (isLocked) {
                // 成功获取到锁
                try {
                    // 模拟业务处理
                    TimeUnit.SECONDS.sleep(5);
                    return "成功获取锁,并执行业务代码";
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    // 释放锁
                    lock.unlock();
                }
            } else {
                // 获取锁失败
                return "获取锁失败";
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "获取锁成功";
    }
}

实现公平锁

Redisson 默认创建的分布式锁是非公平锁(出于性能的考虑),想要把它变成公平锁可使用以下代码实现:

RLock lock = redissonClient.getFairLock(lockKey);  // 获取公平锁

实现读写锁

Redisson 还可以创建读写锁,如下代码所示:

RReadWriteLock lock = redissonClient.getReadWriteLock(lockKey); // 获取读写锁
lock.readLock();  // 读锁
lock.writeLock(); // 写锁

读写锁的特点就是并发性能高,它是允许多个线程同时获取读锁进行读操作的,也就是说在没有写锁的情况下,读取操作可以并发执行,提高了系统的并行度。但写锁则是独占式的,同一时间只有一个线程可以获得写锁,无论是读还是写都无法与写锁并存,这样就确保了数据修改时的数据一致性。

实现联锁

Redisson 也支持联锁,也叫分布式多锁 MultiLock,它允许客户端一次性获取多个独立资源(RLock)上的锁,这些资源可能是不同的键或同一键的不同锁。当所有指定的锁都被成功获取后,才会认为整个操作成功锁定。这样能够确保在分布式环境下进行跨资源的并发控制。联锁的实现示例如下:

// 获取需要加锁的资源
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
// 联锁
RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);
try {
    // 一次性尝试获取所有锁
    if (multiLock.tryLock()) {
        // 获取锁成功...
    }
} finally {
    // 释放所有锁
    multiLock.unlock();
}

课后思考

以上 Redisson 只是对 Redis 单节点加锁实现分布式锁的,但分布式环境中的 Redis 一定采用的是多机部署(主从、哨兵或集群),那么在多机环境下以上代码实现分布式锁还能用吗?如果不能用,那该如何处理呢?

来源:Java中文社群内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯