redisson的几大特性

相信看了这个标题的同学,对这个问题以已经非常不陌生了,信手拈来redisson的几大特性:

可重入性

【多个业务线同一时刻n条扣款,如果用setnx,我怎么监控的加锁解锁线程?死锁不得发生呐?】

redisson使用hash结构,业务名称作为key,uuid 线程id作为field,加锁次数作为value,这不就解决上述问题了吗

阻塞能力

【加锁有两个策略,一是互斥,二是阻塞。互斥比如说定时任务,同一时刻我需要只执行一次就行。阻塞的话-例如多个业务线同一时刻n条扣款,我不能互斥掉吧,那不得被喷死。我得写个while死循环【标准用语就是自旋】一段时间在获取一次,保证系统都能处理这些请求】

续约

加锁过期时间短-加锁逻辑还没执行完就解锁了是不是很尴尬,过长的话-宕机恢复时间又变长

redisson默认30秒给你执行,30秒没执行完就续约30s,宕机的话恢复时间也不会太长。

原理呢就是使用了netty的时间轮实现。简单点说就是环形数组。

直通车:

RedissonLock --> renewExpiration -->TimerTask
Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
    @Override
    public void run(Timeout timeout) throws Exception {
        ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
        if (ent == null) {
            return;
        }
        Long threadId = ent.getFirstThreadId();
        if (threadId == null) {
            return;
        }
        RFuture<Boolean> future = renewExpirationAsync(threadId);
        future.onComplete((res, e) -> {
            if (e != null) {
                log.error("Can't update lock "   getName()   " expiration", e);
                return;
            }
            if (res) {
                // reschedule itself
                renewExpiration();
            }
        });
    }
}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);
// internalLockLeaseTime默认30s,因此这里默认延迟10s后执行
// 其中TimerTask引用的就是netty中的TimerTask

初始化timer的代码

protected void initTimer(MasterSlaveServersConfig config) {
    int[] timeouts = new int[]{config.getRetryInterval(), config.getTimeout()};
    Arrays.sort(timeouts);
    int minTimeout = timeouts[0];
    if (minTimeout % 100 != 0) {
        minTimeout = (minTimeout % 100) / 2;
    } else if (minTimeout == 100) {
        minTimeout = 50;
    } else {
        minTimeout = 100;
    }
    // 就是分成了1024个格子,每个格子默认100ms
    timer = new HashedWheelTimer(new DefaultThreadFactory("redisson-timer"), minTimeout, TimeUnit.MILLISECONDS, 1024, false);
    connectionWatcher = new IdleConnectionWatcher(this, config);
    subscribeService = new PublishSubscribeService(this, config);
}

大白话讲就是:例如将一个圆分成4等分,1,2,3,4,从1到2需要100ms,那么我需要计算延迟500ms需要走几步,下标是多少?

既然是时间总要跳动嘛,没猜错就是sleep😄

  • 红锁

如果redis节点宕机大部分节点同意获取锁,才能获取到锁。

  • 联锁

全部节点加锁成功才算加锁成功。

  • 加锁流程

lua判断锁是否存在

--> 不存在创建hash,当前业务key,uuid 线程id为field,value =1 ,设置过期时间并返回

--> 存在检查uuid 线程id是否一致,一致递增value更新过期时间返回。存在锁检查uuid 线程id不一致,判断是否到期,没到期我就帮你续期,自己加锁也没有成功,就以当前业务key发布消息订阅pubsub,等收到解锁消息在重试

  • 解锁逻辑

lua判断锁是否存在

-->不存在则直接发布解锁消息并返回

-->存在就检查uuid 线程id是否一致,不一致就报错,因为加锁线程不一致。如果一致,就递减value,判断是否大于0,如果等于0,删除key并发布解锁消息

以上就是redisson特性及优雅实现示例的详细内容,更多关于redisson特性及实现的资料请关注Devmax其它相关文章!

redisson特性及优雅实现示例的更多相关文章

  1. PHP实现文件安全下载

    例如你希望客户要填完一份表格,才可以下载某一文件,你第一个想法一定是用"Redirect"的方法,先检查表格是否已经填写完毕和完整,然后就将网址指到该文件,这样客户才能下载,但如果你想做一个关于"网上购物"的电子商务网站,考虑安全问题,你不想用户直接复制网址下载该文件,笔者建议你使用PHP直接读取该实际文件然后下载的方法去做。feof){echofread;}fclose;}这样就可以用PHP直接输出文件了。

  2. 实现“上一页”和“下一页按钮

    offset=$prevoffset\">上一页\n";}//计算页面数$pages=intval;//$pagesnowcontainsintofpagesneededunlessthereisaremainderfromdivisionif{//hasremaindersoaddonepage$pages;}for{//显示页数$newoffset=$limit*;print"

  3. Spring Boot 集成Redisson实现分布式锁详细案例

    这篇文章主要介绍了Spring Boot 集成Redisson实现分布式锁详细案例,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下

  4. 利用PHP实现与ASP Banner组件相似的类

    ********************************************************//*广告条管理程序publicmethodGetAdvertisementparametersTarget=Width=Height=Border=Redirect=*/classAdRotator{var$Target="_blank";var$Width="460";var$Height="60";var$Border=0;var$Redirect="";var$BannerData=ar

  5. 关于分布式锁(Redisson)的原理分析

    这篇文章主要介绍了关于分布式锁(Redisson)的原理,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  6. 用Php实现链结人气统计

    php//功能:传入参数id,在计数文件查找相应的url,增加计数,并返回实际的链接$countfile="count.txt";$lines=file;//将计数文件内容读到数组$lines中for{list=explode;//分解字符串为$id,$url,$countif//查找指定id{$count=1;//增加计数$lines[$i]=$sid."|".$url."|"."$count"."\n";//重新生成计数字符串break;}}//写入计数信息$fp=fopen;forfputs;fcl

  7. Python threading和Thread模块及线程的实现

    这篇文章主要介绍了Python threading和Thread模块及线程的实现,Python通过两个标准库thread和threading提供对线程的支持,threading对thread进行了封装,具体实现介绍需要的朋友可以参考一下下面文章内容

  8. Jsp如何实现网页的重定向

    例如,如果你需要存储或存取applicationscope变量,你总是可以创建一个Javabean,并在页面中需要这些变量的地方将它包含进来。<jsp:useBeanid="globals"scope="application"class="com.xxx.GlobalBean"/>但是,也有一些产品具有这样的对应:Allaire公司的产品JRun3.0将提供global.jsa。JRun2.3.3仍然给予支持,但只对JSP0.92。当JRun3.0最终推出时它将支持用于JSP1.0和1.1的global

  9. 无限级别菜单的实现

    /*看到很多朋友问过无限级别菜单的的问题,我曾经用老大(唠叨)提供的代码写出来过无限级别的菜单,但是感觉效果不是很好(视觉上),于是趁着"夜深人静"就写这个"无限制级别的菜单",其实道理很简单,主要是数据表的设计,还有递归方法的使用,我会在下面给出数据结构的设计,这里我没有加上竖直的虚线,同时Sql语句我也将其固定,大家可以根据自己的需要来修改!ListChildTree;//递归调用函数本身来显示其他孩子节点}//endif?>无限级菜单测试

  10. 详解PHP队列的实现

    这篇文章主要介绍了PHP队列的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部