Redisson 框架详解

目录

一.为什么要使用分布式锁?

二.Redisson 的基本使用:

1.添加 Redisson 依赖:

2.在 application.yml 配置 Redis:

3. 创建 Redisson 客户端:

(1)单节点模式:

(2)集群模式:

4.注入RedissonClient:

5.使用 Redisson 存储和获取值:

三.配置集群连接池:

1. Redisson 集群连接池配置项:

2. 配置 Redis 集群的连接池:

四.如何在Boot项目中使用Redission实现分布式锁?

1.引入 Redisson 依赖:

 2.配置 Redisson:

3.在 Spring Boot 中注入 RedissonClient:

4.使用分布式锁:


Redisson 是一个基于 Redis 的高效 Java 客户端,封装了 Redis 的大部分功能,提供了更为丰富和高效的操作接口,能够帮助开发者更便捷地进行分布式缓存、分布式锁、分布式集合等操作。它不仅支持 Redis 的基本操作,还提供了更多的高级功能,如分布式锁、分布式集合、分布式计数器等,可以大大简化分布式应用的开发。

一.为什么要使用分布式锁?

分布式锁是解决 分布式系统中的资源竞争问题 的一种有效机制。在高并发分布式系统中,多个服务节点可能同时访问同一资源(如数据库、文件系统等)。这种竞争可能导致数据的不一致性、重复操作、死锁等问题,因此,使用分布式锁来保证同一时刻只有一个节点能够访问共享资源,从而确保系统的正确性和稳定性。

在单机系统中,当多个线程访问共享资源时,操作系统通常使用互斥锁(如 Java 中的 synchronizedReentrantLock)来保证同一时刻只有一个线程能访问该资源。而在分布式系统中,资源通常分布在多个服务实例或节点上,单纯的本地锁(如 synchronized)无法跨节点进行协调,因此需要分布式锁来确保不同节点间的同步。

使用分布式锁的方式:

  • 所有节点都尝试获取锁,如果一个节点获得了锁,它将执行任务。
  • 其他节点则会等待或者跳过执行该任务,避免重复执行。

使用场景:

  1. 防止多次执行相同的任务
  2. 确保分布式系统中资源的独占访问
  3. 控制并发数量

二.Redisson 的基本使用:

1.添加 Redisson 依赖:

在项目中使用 Redisson,首先需要添加 Redisson 的 Maven 依赖:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.16.1</version> <!-- 请根据最新版本替换 -->
</dependency>

2.在 application.yml 配置 Redis:

# 单节点
redisson:
  address: redis://127.0.0.1:6379
# 集群
redisson:
  cluster:
    addresses: 
      - redis://127.0.0.1:7000
      - redis://127.0.0.1:7001
      - redis://127.0.0.1:7002

3. 创建 Redisson 客户端:

Redisson 提供了两种方式来创建客户端:单节点模式集群模式

(1)单节点模式:

在单节点模式下,我们只需要连接到一个 Redis 实例,在配置类中:

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

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient() {
        // 配置单节点 Redis
        Config config = new Config();
        SingleServerConfig serverConfig = config.useSingleServer();
        serverConfig.setAddress("redis://127.0.0.1:6379");
        serverConfig.setPassword("yourpassword");
        return Redisson.create(config);
    }
}

(2)集群模式:

import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ClusterServersConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.redisson.Redisson;

import java.util.List;

@Configuration
public class RedissonClusterConfig {

    // 从配置文件中读取 Redis 集群的地址
    @Value("${redisson.cluster.addresses}")
    private List<String> clusterAddresses;

    @Bean
    public RedissonClient redissonClient() {
        // 创建 Redis 配置对象
        Config config = new Config();
        
        // 配置集群
        ClusterServersConfig clusterConfig = config.useClusterServers();
        
        // 添加集群节点地址
        for (String address : clusterAddresses) {
            clusterConfig.addNodeAddress(address);
        }
        
        // 如果需要配置密码,使用 setPassword 方法
        // clusterConfig.setPassword("yourpassword");

        // 创建并返回 Redisson 客户端
        return Redisson.create(config);
    }
}

4.注入RedissonClient:

通过 @Autowired 注入 RedissonClient 到需要使用的服务类中。

import org.redisson.api.RedissonClient;
import org.redisson.api.RMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedisService {

    @Autowired
    private RedissonClient redissonClient;

    public void demoMapUsage() {
        // 获取 Redis 集群中的分布式 Map
        RMap<String, String> map = redissonClient.getMap("myMap");
        map.put("name", "Alice");
        map.put("age", "30");

        System.out.println("Name: " + map.get("name"));
        System.out.println("Age: " + map.get("age"));
    }
}

5.使用 Redisson 存储和获取值:

RBucket<String> 是 Redisson 提供的一个接口,它代表 Redis 中一个字符串类型的值。我们可以通过它来存储和获取一个键值对。

import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RedisService {

    @Autowired
    private RedissonClient redissonClient;

    // 存储值
    public void setValue(String key, String value) {
        RBucket<String> bucket = redissonClient.getBucket(key); // 获取 Redis 中的指定 key
        bucket.set(value);  // 存储值
    }

    // 获取值
    public String getValue(String key) {
        RBucket<String> bucket = redissonClient.getBucket(key); // 获取 Redis 中的指定 key
        return bucket.get(); // 获取存储的值
    }
}

三.配置集群连接池:

在使用 Redisson 配置 Redis 集群时,我们可以通过配置连接池来管理连接的数量、连接的超时时间等。Redisson 提供了灵活的配置方式来定制集群模式的连接池。

1. Redisson 集群连接池配置项:

Redisson 提供了多个与连接池相关的配置项,主要包括以下几个:

  • masterConnectionPoolSize:主节点连接池的大小(连接数量)。
  • slaveConnectionPoolSize:从节点连接池的大小(连接数量)。
  • connectionMinimumIdleSize:连接池中保持的最小空闲连接数。
  • connectionPoolSize:连接池的最大连接数。
  • idleConnectionTimeout:空闲连接的超时时间。
  • connectTimeout:连接的超时时间。
  • timeout:操作超时时间(请求的最大等待时间)。

2. 配置 Redis 集群的连接池:

application.yml 中配置连接池参数:

redisson:
  cluster:
    addresses: 
      - redis://127.0.0.1:7000
      - redis://127.0.0.1:7001
      - redis://127.0.0.1:7002

    # 集群连接池配置
    master-connection-pool-size: 100      # 主节点连接池大小
    slave-connection-pool-size: 50       # 从节点连接池大小
    connection-pool-size: 200            # 总连接池大小
    connection-minimum-idle-size: 10     # 最小空闲连接数
    idle-connection-timeout: 10000       # 空闲连接超时
    connect-timeout: 3000                # 连接超时
    timeout: 5000                        # 请求超时

配置连接池是确保 Redis 集群高效运行的关键,它能够有效管理连接的数量,提高 Redis 的性能,避免频繁地创建和销毁连接。

如果我们在 application.ymlapplication.properties 文件中配置了 Redisson 的连接池参数,并且使用了 redisson-spring-boot-starter,Spring Boot 会自动读取这些配置并初始化连接池。

四.如何在Boot项目中使用Redission实现分布式锁?

在 Spring Boot 项目中使用 Redisson 实现分布式锁,主要涉及到以下几个步骤:

  1. 引入 Redisson 依赖
  2. 配置 Redisson 客户端
  3. 在 Spring Boot 中注入 RedissonClient
  4. 使用分布式锁

1.引入 Redisson 依赖:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.16.1</version> <!-- 请根据最新版本替换 -->
</dependency>

 2.配置 Redisson:

redisson:
  # Redis 集群配置
  cluster:
    # 集群节点地址,多个节点地址用逗号分隔
    nodes:
      - redis://127.0.0.1:7000
      - redis://127.0.0.1:7001
      - redis://127.0.0.1:7002
      - redis://127.0.0.1:7003
      - redis://127.0.0.1:7004
      - redis://127.0.0.1:7005
    # Redis 密码(如果有密码的话)
    password: yourpassword  # Redis 的密码

    # 连接池配置
    connection-pool-size: 100            # 连接池大小
    connection-minimum-idle-size: 10     # 最小空闲连接数
    idle-connection-timeout: 10000       # 空闲连接超时(毫秒)
    connect-timeout: 3000                # 连接超时(毫秒)
    timeout: 5000                        # 请求超时(毫秒)
    retries: 3                           # 在获取连接时的最大重试次数
    retry-interval: 1000                 # Redis 集群模式下的超时时间
    wait-timeout: 3000                   # 最大等待连接的时间(毫秒)
    subscription-mode: false             # 集群模式下是否启用超时管理
    threads: 16                          # 线程池大小

3.在 Spring Boot 中注入 RedissonClient:

在 Spring Boot 中,我们可以通过 @Autowired 注入 RedissonClient,然后在服务类中使用它进行 Redis 操作。

import org.redisson.api.RLock;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class RedisWithLockService {

    @Autowired
    private RedissonClient redissonClient;

    // 锁的名称
    private static final String LOCK_KEY = "myLock";

    // 存储到 Redis 中的键
    private static final String REDIS_KEY = "userBalance";

    // 分布式锁处理业务逻辑
    public void updateBalance(String userId, double newBalance) {
        // 获取分布式锁
        RLock lock = redissonClient.getLock(LOCK_KEY);

        try {
            // 尝试获取锁,最多等待 10 秒,锁自动释放时间为 30 秒
            if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {
                // 锁获取成功,执行 Redis 操作
                System.out.println("Lock acquired, updating balance...");

                // 获取当前用户的余额
                double currentBalance = getUserBalanceFromRedis(userId);
                System.out.println("Current balance: " + currentBalance);

                // 更新余额(模拟业务逻辑)
                double updatedBalance = currentBalance + newBalance;
                System.out.println("Updated balance: " + updatedBalance);

                // 将新的余额存储回 Redis
                setUserBalanceToRedis(userId, updatedBalance);

            } else {
                System.out.println("Unable to acquire lock for updating balance.");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 确保释放锁
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    // 获取用户余额(从 Redis 中)
    private double getUserBalanceFromRedis(String userId) {
        RBucket<Double> bucket = redissonClient.getBucket(REDIS_KEY + ":" + userId);
        return bucket.isExists() ? bucket.get() : 0.0; // 如果值存在则获取,如果没有则返回 0
    }

    // 更新用户余额(存入 Redis)
    private void setUserBalanceToRedis(String userId, double balance) {
        RBucket<Double> bucket = redissonClient.getBucket(REDIS_KEY + ":" + userId);
        bucket.set(balance);  // 存储新的余额
    }
}

4.使用分布式锁:

RedisLockService 中定义了 processWithDistributedLock 方法,调用时,Redisson 将确保在同一时刻只有一个进程/线程可以进入锁的保护区域。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RedisWithLockController {

    @Autowired
    private RedisWithLockService redisWithLockService;

    // 模拟调用分布式锁更新用户余额的接口
    @GetMapping("/updateBalance")
    public String updateBalance(@RequestParam String userId, @RequestParam double amount) {
        redisWithLockService.updateBalance(userId, amount);
        return "Balance update request received for user: " + userId;
    }
}

通过访问下面接口地址:

http://localhost:8080/updateBalance?userId=user1&amount=100

 查看后端返回数据。

总结:

  • Redisson 提供了丰富的 API 用于存储和获取 Redis 中的值。你可以通过 RBucket 等数据结构操作 Redis 中的数据。
  • 使用 分布式锁 可以确保在多个服务实例之间协调对共享资源(如 Redis 中的数据)的访问。
  • Redisson 的分布式锁非常适合用来保护 Redis 中的临界资源,避免高并发访问导致的数据不一致问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/942497.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes PV及PVC的使用

前提条件 拥有Kubernetes集群环境&#xff0c;可参考&#xff1a;Kubernetes集群搭建理解Kubernetes部署知识&#xff0c;可参考&#xff1a;使用Kubernetes部署第一个应用 、Deloyment控制器拥有NFS服务&#xff0c;可参考&#xff1a;Linux环境搭建NFS服务 概述 Persistent…

flink sink kafka

接上文&#xff1a;一文说清flink从编码到部署上线 之前写了kafka source&#xff0c;现在补充kafka sink。完善kafka相关操作。 环境说明&#xff1a;MySQL&#xff1a;5.7&#xff1b;flink&#xff1a;1.14.0&#xff1b;hadoop&#xff1a;3.0.0&#xff1b;操作系统&#…

【安全编码】Web平台如何设计防止重放攻击

我们先来做一道关于防重放的题&#xff0c;答案在文末 防止重放攻击最有效的方法是&#xff08; &#xff09;。 A.对用户密码进行加密存储使用 B.使用一次一密的加密方式 C.强制用户经常修改用户密码 D.强制用户设置复杂度高的密码 如果这道题目自己拿不准&#xff0c;或者…

Diagramming AI: 使用自然语言来生成各种工具图

前言 在画一些工具图时&#xff08;流程图、UML图、架构图&#xff09;&#xff0c;你还在往画布上一个个的拖拽组件来进行绘制么&#xff1f;今天介绍一款更有效率的画图工具&#xff0c;它能够通过简单的自然语言描述来完成一个个复杂的图。 首页 进入官网之后&#xff0c;我…

黑马Java面试教程_P9_MySQL

系列博客目录 文章目录 系列博客目录前言1. 优化1.1 MySQL中&#xff0c;如何定位慢查询&#xff1f;面试文稿 1.2 面试官接着问&#xff1a;那这个SQL语句执行很慢,如何分析 ( 如何优化&#xff09;呢?面试文稿 1.3 了解过索引吗?(什么是索引)1.4 继续问 索引的底层数据结构…

Windows11家庭版启动Hyper-V

Hyper-V 是微软的硬件虚拟化产品&#xff0c;允许在 Windows 上以虚拟机形式运行多个操作系统。每个虚拟机都在虚拟硬件上运行&#xff0c;可以创建虚拟硬盘驱动器、虚拟交换机等虚拟设备。使用虚拟化可以运行需要较旧版本的 Windows 或非 Windows 操作系统的软件&#xff0c;以…

第6章 图论

2024年12月25日一稿 &#x1f430;6.1 图的基本概念 6.1.1 图的定义和表示 6.1.2 图的同构 6.1.3 完全图与正则图 6.1.4 子图与补图 6.1.5 通路与回路 6.2 图的连通性 6.2.1 无向图的连通性 6.2.2 有向图的连通性 6.3 图的矩阵表示 6.3.1 关联矩阵 6.3.2 有向图的邻接矩阵…

智能网关在电力物联网中的应用

摘要 随着电力技术的快速发展&#xff0c;断路器从传统的单一保护功能演变为具备智能监控和远程管理能力的多功能设备。智能断路器作为配电系统的重要组成部分&#xff0c;集成了实时监测、远程控制和多层保护功能&#xff0c;显著提升了配电系统的安全性、稳定性和管理效率…

【论文阅读】Comprehensive Review of End-to-End Video Compression

摘要&#xff1a; 近年来&#xff0c;端到端视频压缩作为一种新兴且有前景的解决方案开始在视频压缩领域受到关注。本文对端到端视频编码和解码技术的发展与现状进行了全面的综述&#xff0c;详细介绍了传统混合编码器和端到端编码器的基本原理。本研究深入探讨了从传统视频压…

系统架构师考试 常错题记录 01

1.按照《中华人民共和国著作权法》的权利保护期&#xff08; &#xff09;受到永久保护。 A.发表权 B.修改权 C.复制权 D.发行权 正确答案&#xff1a;B 解析&#xff1a;本题考查知识产权法中的《中华人民共和著作权法》保护期限知识点。 《中华人民共和著作权法》中约定署名权…

Redis-十大数据类型

Reids数据类型指的是value的类型&#xff0c;key都是字符串 redis-server:启动redis服务 redis-cli:进入redis交互式终端 常用的key的操作 redis的命令和参数不区分大小写 &#xff0c;key和value区分 1、查看当前库所有的key keys * 2、判断某个key是否存在 exists key 3、查…

IIC驱动EEPROM

代码参考正点原子 i2c_dri:主要是三段式状态机的编写 module iic_dri#(parameter SLAVE_ADDR 7b1010000 , //EEPROM从机地址parameter CLK_FREQ 26d50_000_000, //模块输入的时钟频率parameter I2C_FREQ 18d250_000 //IIC_SCL的时钟频率)( …

webrtc获取IceCandidate流程

在WebRTC(Web Real-Time Communication)中,ICECandidate是一个关键概念,它用于描述在建立点对点(P2P)连接时可以考虑的潜在通信端点。以下是关于WebRTC中ICECandidate的详细解释: 一、ICECandidate的定义 ICECandidate对象通常包含以下关键属性: foundation:用于唯一…

一文彻底拿捏DevEco Studio的使用小技巧

程序员Feri一名12年的程序员,做过开发带过团队创过业,擅长Java相关开发、鸿蒙开发、人工智能等,专注于程序员搞钱那点儿事,希望在搞钱的路上有你相伴&#xff01;君志所向,一往无前&#xff01; 0.安装DevEco Studio DevEco Studio面向HarmonyOS应用及元服务开发者提供的集成开…

基于openEuler22.09部署OpenStack Yoga云平台(一)

OpenStack Yoga部署 安装OpenStack 一、基础准备 基于OpenStack经典的三节点环境进行部署&#xff0c;三个节点分别是控制节点&#xff08;controller&#xff09;、计算节点&#xff08;compute&#xff09;、存储节点&#xff08;storage&#xff09;&#xff0c;其中存储…

新服务器ubuntu系统相关操作

1、查看驱动:驱动版本535.216.01能够支持cuda12.2,下面直接使用默认安装的cuda。 2、赋予用户管理员权限。 首先有超级用户(root)权限来编辑 /etc/sudoers 文件,visudo 是一个命令,用于安全地编辑 /etc/sudoers 文件。运行: sudo visudo 在 visudo 编辑器中,找到类似…

微机接口课设——基于Proteus和8086的打地鼠设计(8255、8253、8259)

原理图设计 汇编代码 ; I/O 端口地址定义 IOY0 EQU 0600H IOY1 EQU 0640H IOY2 EQU 0680HMY8255_A EQU IOY000H*2 ; 8255 A 口端口地址 MY8255_B EQU IOY001H*2 ; 8255 B 口端口地址 MY8255_C EQU IOY002H*2 ; 8255 C 口端口地址 MY8255_MODE EQU IOY003H*2 ; …

【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】

目录&#x1f60b; 任务描述 相关知识 1. 二叉树的基本概念与结构定义 2. 建立二叉树 3. 先序遍历 4. 中序遍历 5. 后序遍历 6. 层次遍历 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;实现二叉树的遍历 相关知识 为了完成本关任务&#xff0c;你需要掌…

简单园区网拓扑实验

1.实验拓扑 2.实验要求 1、按照图示的VLAN及IP地址需求&#xff0c;完成相关配置 2、要求SW1为VLAN 2/3的主根及主网关 SW2为vlan 20/30的主根及主网关 SW1和SW2互为备份 3、可以使用super vlan 4、上层通过静态路由协议完成数据通信过程 5、AR1为企业出口路由器 6、要求全网可…

USB接口实现CDC(usb转串口功能)

主控&#xff1a;stm32f429 PHY芯片&#xff1a;usb3320 Cubemx System Core-RCC connectivity-USB_OTG_HS Middleware and Software Packs-USB_DEVICE 时钟配置&#xff1a;根据自己使用的MCU工作频率设置 Generate Code Keil5 打开工程 usbd_cdc_if.c这个文件&…