Redisson使用分布锁的详解

1. 添加依赖

pom.xml 中引入 Redisson 和 Spring Boot Starter 依赖:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.23.4</version> <!-- 使用最新稳定版本 -->
</dependency>

2. 配置 Redisson 客户端

application.yml 中配置 Redisson(支持单节点、哨兵、集群模式):

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: your_password
    database: 0

# Redisson 高级配置(可选)
redisson:
  config: |
    singleServerConfig:
      idleConnectionTimeout: 10000
      connectTimeout: 10000
      timeout: 3000
      retryAttempts: 3
      retryInterval: 1500
      subscriptionsPerConnection: 5
      clientName: "my-service"
      # 哨兵/集群模式配置示例:
      # sentinelServersConfig:
      #   masterName: "mymaster"
      #   sentinelAddresses:
      #     - "redis://sentinel1:26379"
      #     - "redis://sentinel2:26379"

3. 注入 RedissonClient

Spring Boot 会自动根据配置创建 RedissonClient Bean:

@Autowired
private RedissonClient redissonClient;

4. 实现分布式锁

基本锁操作(可重入锁)
public void executeWithLock(String lockKey) {
    RLock lock = redissonClient.getLock(lockKey);
    try {
        // 尝试加锁,最多等待 10 秒,锁自动释放时间 30 秒
        boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
        if (isLocked) {
            // 执行业务逻辑
            processBusiness();
        } else {
            log.warn("获取锁失败,其他节点正在处理");
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        log.error("锁等待被中断", e);
    } finally {
        if (lock.isHeldByCurrentThread()) {
            lock.unlock(); // 确保只有持有锁的线程才能解锁
        }
    }
}

5. 高级锁特性

自动续期(看门狗机制)

Redisson 默认在未指定 leaseTime 时启用看门狗(锁自动续期):

lock.lock(); // 看门狗默认每隔 30/3=10 秒续期一次
try {
    // 长时间任务(锁不会自动过期)
    processLongTimeTask();
} finally {
    lock.unlock();
}
公平锁
RLock fairLock = redissonClient.getFairLock("fairLock");
fairLock.lock();
try {
    // 公平执行业务
} finally {
    fairLock.unlock();
}
联锁(MultiLock)

同时获取多个锁,确保原子性:

RLock lock1 = redissonClient.getLock("lock1");
RLock lock2 = redissonClient.getLock("lock2");
RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);
multiLock.lock();
try {
    // 需要同时占用 lock1 和 lock2 的业务
} finally {
    multiLock.unlock();
}

6. 异常处理与最佳实践

确保锁释放

使用 try-finally 块确保锁被释放,避免死锁:

java

复制

下载

finally {
    if (lock != null && lock.isHeldByCurrentThread()) {
        lock.unlock();
    }
}
避免锁超时
  • 短任务:手动指定 leaseTime(禁用看门狗)。
  • 长任务:依赖看门狗自动续期,但需确保任务可中断。

7. Redisson 高可用配置

Redis 集群模式配置
redisson:
  config: |
    clusterServersConfig:
      nodeAddresses:
        - "redis://node1:6379"
        - "redis://node2:6379"
        - "redis://node3:6379"
      scanInterval: 2000 # 集群状态扫描间隔
      retryAttempts: 3
      retryInterval: 1500
RedLock 算法(多 Redis 主节点)
Config config1 = new Config();
config1.useSingleServer().setAddress("redis://node1:6379");
RedissonClient client1 = Redisson.create(config1);

Config config2 = new Config();
config2.useSingleServer().setAddress("redis://node2:6379");
RedissonClient client2 = Redisson.create(config2);

RLock lock1 = client1.getLock("lock");
RLock lock2 = client2.getLock("lock");
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2);

redLock.lock();
try {
    // 业务逻辑
} finally {
    redLock.unlock();
}

8. 监控与调试

启用 Redisson 监控

application.yml 中开启 JMX 监控:

redisson:
  config: |
    jmxEnabled: true
日志配置

logback-spring.xml 中增加 Redisson 日志:

<logger name="org.redisson" level="DEBUG" additivity="false">
    <appender-ref ref="CONSOLE"/>
</logger>

完整示例场景

订单处理服务(防重复提交)
@Service
public class OrderService {
    
    @Autowired
    private RedissonClient redissonClient;
    
    public void createOrder(String orderId) {
        RLock lock = redissonClient.getLock("order_lock:" + orderId);
        try {
            if (lock.tryLock(5, 30, TimeUnit.SECONDS)) {
                // 检查订单是否已存在
                if (orderExists(orderId)) {
                    throw new RuntimeException("订单重复提交");
                }
                // 创建订单
                saveOrder(orderId);
            }
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

注意事项

  1. 网络分区:Redis 集群需配置合理的超时和重试参数。
  2. 锁粒度:锁的 key 应足够具体(如 order_lock:1001),避免全局锁竞争。
  3. 性能影响:分布式锁会引入延迟,非必要场景尽量使用本地锁。
  4. 版本兼容:确保 Redisson 版本与 Spring Boot 和 Redis Server 兼容。

通过以上方案,可以在 Spring Cloud 项目中安全、高效地实现分布式锁,覆盖高并发、高可用场景需求。

这段配置是 Redisson 客户端连接单节点 Redis 的配置参数,主要用于优化性能和稳定性。以下是各参数的详细解释:

核心参数解释

1. 连接池配置

yaml

singleServerConfig:
  idleConnectionTimeout: 10000      # 空闲连接超时时间(毫秒),默认10000ms
  connectTimeout: 10000            # 连接超时时间(毫秒),默认10000ms
  timeout: 10000                   # 命令执行超时时间(毫秒),默认3000ms


 

  • idleConnectionTimeout:连接空闲多久后断开(默认 10 秒),避免长时间占用资源。
  • connectTimeout:建立连接的最大等待时间,超时则抛异常。
  • timeout:命令执行的最大等待时间(如 SETGET 操作),防止长时间阻塞。
2. 重试机制

yaml

retryAttempts: 3                 # 命令失败重试次数,默认3次
  retryInterval: 50                # 重试间隔时间(毫秒),默认1500ms


 

  • retryAttempts:当命令失败(如网络抖动)时,自动重试的次数。
  • retryInterval:每次重试的间隔时间,避免频繁重试加重服务器负担。
3. 订阅配置

yaml

subscriptionsPerConnection: 5    # 每个连接的最大订阅数量,默认5
  • 控制单个 Redis 连接可处理的订阅(如发布 - 订阅模式)数量。
  • 高并发场景下需根据业务调整,避免连接耗尽。
4. 客户端标识

yaml

clientName: "xxx-service"  # 客户端名称,用于Redis监控
  • 在 Redis 服务器的 CLIENT LIST 命令中显示的客户端标识,便于排查问题。

参数优化建议

  1. 超时参数调整
    • 若 Redis 响应较慢(如复杂操作),可增大 timeout(如 30000ms)。
    • 网络不稳定时,增大 retryAttemptsretryInterval
  1. 性能优化
    • 高并发场景下,增加 subscriptionsPerConnection(如 10-20)。
    • 对于读写分离场景,考虑使用 masterSlaveConfigclusterConfig
  1. 监控与调试
    • 通过 clientName 可在 Redis 中识别特定客户端的连接状态。
    • 结合 Redis 的 slowlog 监控命令执行耗时。

完整配置示例

yaml

redisson:
  config: |
    singleServerConfig:
      address: "redis://127.0.0.1:6379"
      password: null
      database: 0
      idleConnectionTimeout: 10000
      connectTimeout: 10000
      timeout: 10000
      retryAttempts: 3
      retryInterval: 50
      subscriptionsPerConnection: 5
      clientName: "performance-meeting-service"
      subscriptionConnectionMinimumIdleSize: 1
      subscriptionConnectionPoolSize: 50
      connectionMinimumIdleSize: 10
      connectionPoolSize: 64
      dnsMonitoringInterval: 5000
    codec: !<org.redisson.codec.JsonJacksonCodec> {}


 

以上配置结合了连接池大小、订阅连接池等参数,可根据实际业务量调整。

要评估你提供的 Redisson 配置能抗住的并发数,需要综合分析多个因素。以下是基于你提供的配置参数的详细分析:

配置参数解读

singleServerConfig:
  idleConnectionTimeout: 10000  # 空闲连接超时时间(ms)
  connectTimeout: 10000         # 连接超时时间(ms)
  timeout: 10000                # 操作超时时间(ms)
  retryAttempts: 5              # 失败重试次数
  retryInterval: 1000           # 重试间隔(ms)
  subscriptionsPerConnection: 6 # 每个连接最大订阅数
  clientName: "xx-service"

关键影响因素

  1. 缺失的核心参数
    • 未配置 connectionPoolSize(连接池大小,默认值通常为64)
    • 未配置 subscriptionConnectionPoolSize(订阅专用连接池大小)
  1. 并发能力决定因素
    • 连接池大小:直接影响最大并发操作数
    • 订阅连接池:影响最大并发订阅能力
    • 网络延迟:10秒的超时设置对高并发场景可能过长
    • Redis服务器性能:单节点Redis的QPS上限(通常5万-10万)

并发估算模型

1. 普通命令操作并发

假设使用默认 connectionPoolSize: 64

  • 理论最大并发 ≈ 连接池大小 × 每个连接处理能力
  • 在低延迟网络环境下,每个连接可支持约500-1000 QPS
  • 理论峰值:64 × 500 ≈ 32,000 QPS
2. 订阅操作并发

假设使用默认 subscriptionConnectionPoolSize: 50

  • 每个订阅连接可支持6个订阅(subscriptionsPerConnection: 6
  • 最大订阅数:50 × 6 = 300个并发订阅

优化建议

  1. 明确设置连接池

yaml

复制

下载

connectionPoolSize: 128        # 普通命令连接池
subscriptionConnectionPoolSize: 100  # 订阅专用连接池
  1. 调整超时时间(针对高并发优化):

yaml

复制

下载

connectTimeout: 3000    # 建议3秒
timeout: 5000          # 建议5秒
idleConnectionTimeout: 30000  # 空闲连接可适当延长
  1. 监控指标
    • 监控Redis的connected_clients
    • 监控Redisson的waitingForConnection指标
    • 观察Redis服务器CPU和内存使用率

实际并发支持能力

场景

默认配置(估算)

优化后配置(估算)

普通命令操作(QPS)

30,000-50,000

50,000-100,000

并发订阅连接数

300

600

突发流量承受能力

中等

注意:实际性能需通过压力测试验证,以上数字基于典型场景估算。建议使用JMeter或Redisson自带的性能测试工具进行实际测试。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值