首页 > 数据库 >分布式锁优化(基于redisson实现)

分布式锁优化(基于redisson实现)

时间:2023-10-24 23:01:40浏览次数:36  
标签:redisson log lock .... 获取 isLock 优化 分布式

基于setnx实现的分布式锁存在下面的问题:

1.不可重入

同一个线程无法多次获取同一把锁

2.不可重试

获取锁只尝试一次就返回false,没有重试机制

3.超时释放

锁超时释放虽然可以避免死锁,但如果是业务执行耗时较长,也会导致锁释放,存在安全隐患

4.主从一致性(主写从读)

如果Redis提供了主从集群,主从同步存在延迟,当主宕机时,如果从并同步主中的锁数据,则会出现锁实现


Redission

Redisson是一 个在Redis的基础.上实现的ava驻内存数据网格(In-Memory Data Grid) 。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。

分布式锁优化(基于redisson实现)_Redis

官网地址: https://redisson.org/

GitHub地址: https://github.com/redisson/redisson

引入依赖
<!--redisson-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.6</version>
</dependency>
配置redisson java客户端
@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient(){
        // 配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.40.128:6379").setPassword("root");
        // 创建RedissonClient对象
        return Redisson.create(config);
    }
}
使用redisson的分布式锁
private void createVoucherOrder(VoucherOrder voucherOrder) {
Long userId = voucherOrder.getUserId();
Long voucherId = voucherOrder.getVoucherId();
// 创建锁对象
RLock redisLock = redissonClient.getLock("lock:order:" + userId);
// 尝试获取锁
boolean isLock = redisLock.tryLock();
// 判断
if (!isLock) {
    // 获取锁失败,直接返回失败或者重试
    log.error("不允许重复下单!");
    return;
}
}

分布式锁优化(基于redisson实现)_分布式锁_02

可重入锁

什么是可重入锁?

https://blog.csdn.net/u014571143/article/details/126357814

@Slf4j
@SpringBootTest
class RedissonTest {

    @Resource
    private RedissonClient redissonClient;

    private RLock lock;

    @BeforeEach
    void setUp() {
        lock = redissonClient.getLock("order");
    }

    @Test
    void method1() throws InterruptedException {
        // 尝试获取锁
        boolean isLock = lock.tryLock(1L, TimeUnit.SECONDS);
        if (!isLock) {
            log.error("获取锁失败 .... 1");
            return;
        }
        try {
            log.info("获取锁成功 .... 1");
            method2();
            log.info("开始执行业务 ... 1");
        } finally {
            log.warn("准备释放锁 .... 1");
            lock.unlock();
        }
    }
    void method2() {
        // 尝试获取锁
        boolean isLock = lock.tryLock();
        if (!isLock) {
            log.error("获取锁失败 .... 2");
            return;
        }
        try {
            log.info("获取锁成功 .... 2");
            log.info("开始执行业务 ... 2");
        } finally {
            log.warn("准备释放锁 .... 2");
            lock.unlock();
        }
    }
}

分布式锁优化(基于redisson实现)_分布式锁_03

使用的是Redis的hash数据结构,key为线程名称,value为获取锁的次数

分布式锁优化(基于redisson实现)_Redis_04

分布式锁优化(基于redisson实现)_锁需约_05

分布式锁优化(基于redisson实现)_redisson_06

watchDog机制

分布式锁优化(基于redisson实现)_watchdog_07

注意:只有超时释放时间为-1时,才会开启watchDog,如果提前设置了超时释放时间,不会开启watchDog

watchDog 默认续约时间是30秒

Redisson分布式锁原理:

可重入:利用hash结构记录线程id和重入次数

可重试:利用信号量和PubSub功能实现等待、唤醒,获取锁失败的重试机制

超时续约:利用watchDog,每隔一段时间(releaseTime/3),重置超时时间

标签:redisson,log,lock,....,获取,isLock,优化,分布式
From: https://blog.51cto.com/AmbitionGarden/8011237

相关文章

  • 关于斜率优化的一些杂谈
    这里并不是在详细地介绍斜率优化,只是一些瞎扯,想真正系统学习斜率优化的话请去阅读其他文章。斜率优化是众多dp优化方式中较为常见的一种,让我们不妨回忆一下它的形式:\[dp(i)=\min/\max(a(i)\timesb(j)+c(i)+d(j)+C)\]上式中,\(a,b,c,d\)分别为只跟\(i\)或\(j\)相关的函数......
  • pjsip内存优化及提升视频呼叫并发数
      工作上的一个上层调度台应用(Windows7),业务功能上有并发调取多个视频的需求,发现调取30左右路D1视频后会导致崩溃,日志提示:except.c !!!FATAL:unhandledexceptionPJLIB/Nomemory!,内存不足,在开发环境下验证发现内存占用已经达到2G以上(32位程序默认最高给2G内存,通过配置能......
  • 关于 React 性能优化和数栈产品中的实践
    我们是袋鼠云数栈UED团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。本文作者:的卢引入在日常开发过程中,我们会使用很多性能优化的API,比如像使用memo、useMemo优化组件或者值,再比如使用shouldComponentUpdate减......
  • 数据集与模型的优化策略
    随着人工智能技术的快速发展,神经网络作为其核心组成部分,已经在各个领域取得了显著的成果。而神经网络的性能优劣,往往取决于其训练数据集和训练模型的选择与设计。本文将围绕这一主题,对神经网络训练数据集和神经网络训练模型进行详细阐述。神经网络训练数据集神经网络训练数据集是神......
  • 分布式定时任务-利用分布式定时任务框架xxl-job实现任务动态发布
     1.场景:项目前期使用k8s部署的单节点,后期生产需要将单节点的服务扩展多个节点,每个节点的定时任务使用的quartz实现,如果不加限制且定时任务有对数据库的写操作,在不同节点上执行的定时任务容易造成数据库产生脏数据,所以需要分布式任务框架对任务进行控制,这里我们使用xxl-job实现。......
  • 分布式事务
    本地事务在分布式下会出现的问题只能各自回滚各自的簇点头那边抛出异常--->全部回滚(ok)簇点第一个远程调用返回code不正确,我们可在主方法这抛异常(ok)簇点非第一个远程调用code不正确,我们只有那个远程调用和主方法会rollback,在其之前的远程调用无法rollback没人通知(NO)......
  • WPF ItemsControl 卡顿 数据量大 虚拟化 优化
    <ItemsControlItemsSource="{BindingMemberInfos}"VirtualizingStackPanel.IsVirtualizing="True"VirtualizingStackPanel.VirtualizationMode="Recycling"VirtualizingPanel.CacheLength="50">......
  • 谷粒商城分布式基础(一)—— 项目简介 & 分布式基础
     目录一项目简介1、项目背景二、分布式基础概念 分布式基础篇回到顶部一项目简介1、项目背景1.1电商模式市面上有5种常见的电商模式B2B、B2C、C2B、C2C、O2O;(1)B2B模式B2B(BusinesstoBusiness),是指商家和商家建立的商业关系,如阿里巴巴(2)B2C模式......
  • MySQL中大量数据优化方案
    目录1大量数据优化1.1引言1.2评估表数据体量1.2.1表容量1.2.2磁盘空间1.2.3实例容量1.3出现问题的原因1.4解决问题1.4.1数据表分区1.4.1.1简介1.4.1.2优缺点1.4.1.2操作1.4.2数据库分表1.4.2.1简介1.4.2.2分库分表方案1.4.2.2.1取模方案1.4.2.2.2range范围方案1......
  • 安防视频监控平台EasyCVR查询告警后,无法自动清除记录该如何优化?
    视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多路视频流,也能支持视频定时轮播。视频监控平台EasyCVR支持多种播放协议,包括:HLS、HTT......