这个用户很懒,还没有个人简介
私信
主帖 92
回帖
视频
提问
回答
资源
专栏
十四、Redis分布式锁存在的问题对于单Redis实例来说,如果Redis宕机了,那么整个系统就无法工作了。所以为了保证Redis的高可用性,一般会使用主从或者哨兵模式。但是如果使用了主从或者哨兵模式,此时Redis的分布式锁的功能可能就会出现问题。举个例子来说,假如现在使用了哨兵模式,如图。基于这种模式,Redis客户端会在master节点上加锁,然后异步复制给slave节点。但是突然有一天,因为一些原因,master节点宕机了,那么哨兵...
2022-06-20 17:39:22 145浏览 0点赞 0回复 0收藏
大家好。我们都知道,Spring可以通过三级缓存解决循环依赖的问题,这也是面试中很常见的一个面试题,本文就来着重讨论一下有关循环依赖和三级缓存的问题。一、什么是循环依赖大家平时在写业务的时候应该写过这样的代码。其实这种类型就是循环依赖,就是AService和BService两个类相互引用。二、三级缓存可以解决的循环依赖场景如上面所说,大家平时在写这种代码的时候,项目其实是可以起来的,也就是说其实三级缓存是可以解决这...
2022-06-20 17:39:15 179浏览 0点赞 0回复 0收藏
四、三级缓存指的是哪三级缓存这里直接上源码第一级缓存:singletonObjects存放已经完完全全创建好的Bean,什么叫完完全全创建好的?就是上面说的是,所有的步骤都处理完了,就是创建好的Bean。一个Bean在产的过程中是需要经历很多的步骤,在这些步骤中可能要处理Autowired注解,又或是处理Transcational注解,当需要处理的都处理完之后的Bean,就是完完全全创建好的Bean,这个Bean是可以用来使用的,我们平时在用的Bean其实就...
2022-06-20 17:39:08 128浏览 0点赞 0回复 0收藏
于是接下来就把早期的AService对象注入给BService。此时BService的Autowired注解注入AService对象就完成了,之后再经过其他阶段的处理之后,BService对象就完完全全的创建完了。BService对象创建完之后,就会将BService放入第一级缓存,然后清空BService对应的第三级缓存,当然也会去清空第二级缓存,只是没有而已,至于为什么清空,很简单,因为BService已经完全创建好了,如果需要BService那就在第一级缓存中就能查找到,不需...
2022-06-20 17:38:39 150浏览 0点赞 0回复 0收藏
六、三级缓存无法解决的循环依赖场景1)构造器注入无法解决循环依赖上面的例子是通过Autowired注解直接注入依赖的对象,但是如果通过构造器注入循环依赖的对象,是无法解决的,如代码下构造器注入就是指创建AService对象的时候,就传入BService对象,而不是用Autowired注解注入BService对象。运行结果启动时就会报错,所以通过构造器注入对象就能避免产生循环依赖的问题,因为如果有循环依赖的话,那么就会报错。至于三级缓存为...
2022-06-20 17:38:29 163浏览 0点赞 0回复 0收藏
十二、如何实现读写锁在实际的业务场景中,其实会有很多读多写少的场景,那么对于这种场景来说,使用独占锁来加锁,在高并发场景下会导致大量的线程加锁失败,阻塞,对系统的吞吐量有一定的影响,为了适配这种读多写少的场景,Redisson也实现了读写锁的功能。读写锁的特点:读与读是共享的,不互斥读与写互斥写与写互斥Redisson使用读写锁的代码。Redisson通过RedissonReadWriteLock类来实现读写锁的功能,通过这个类可以获取到...
2022-06-17 16:58:10 330浏览 0点赞 0回复 0收藏
八、如何实现不同线程加锁的互斥上面我们分析了第一次加锁逻辑和可重入加锁的逻辑,因为lua脚本加锁的逻辑同时只有一个线程能够执行(redis是单线程的原因),所以一旦有线程加锁成功,那么另一个线程来加锁,前面两个if条件都不成立,最后通过调用redis的pttl命令返回锁的剩余的过期时间回去。这样,客户端就根据返回值来判断是否加锁成功,因为第一次加锁和可重入加锁的返回值都是nil,而加锁失败就返回了锁的剩余过期时间。...
2022-06-17 16:57:57 254浏览 0点赞 0回复 0收藏
六、如何主动释放锁和避免其它线程释放了自己加的锁当业务执行完成之后,肯定需要主动释放锁,那么为什么需要主动释放锁呢?第一,假设你任务执行完,没有手动释放锁,如果没有指定锁的超时时间,那么因为有看门狗机制,势必会导致这个锁无法释放,那么就可能造成死锁的问题。第二,如果你指定了锁超时时间(锁超时自动释放逻辑后面会说),虽然并不会造成死锁的问题,但是会造成资源浪费的问题。假设你设置的过期时间是30s,但...
2022-06-17 16:57:47 268浏览 0点赞 0回复 0收藏
三、为什么需要设置加锁key的过期时间通过上面的加锁逻辑可以知道,虽然我们没有手动设置锁的过期时间,但是Redisson默认会设置一个30s的过期时间,为什么需要过期时间呢?主要原因是为了防止死锁。当某个客户端获取到锁,还没来得及主动释放锁,那么此时假如客户端宕机了,又或者是释放锁失败了,那么如果没有设置过期时间,那么这个锁key会一直在,那么其它线程来加锁的时候会发现key已经被加锁了,那么其它线程一直会加锁失...
2022-06-17 16:57:36 246浏览 0点赞 0回复 0收藏
大家好,我是三友。在一个分布式系统中,由于涉及到多个实例同时对同一个资源加锁的问题,像传统的synchronized、ReentrantLock等单进程情况加锁的api就不再适用,需要使用分布式锁来保证多服务实例之间加锁的安全性。常见的分布式锁的实现方式有zookeeper和redis等。而由于redis分布式锁相对于比较简单,在实际的项目中,redis分布式锁被用于很多实际的业务场景中。redis分布式锁的实现中又以Redisson比较出名,所以本文来着重...
2022-06-17 16:57:25 814浏览 0点赞 0回复 0收藏
大家好,今天给大家介绍一款轻量、快速、稳定可编排的组件式规则引擎框架LiteFlow。一、LiteFlow的介绍LiteFlow官方网站和代码仓库地址官方网站:https:yomahub.comliteflowGitee托管仓库:https:gitee.comdromaraliteFlowGithub托管仓库:https:github.comdromaraliteflow前言在每个公司的系统中,总有一些拥有复杂业务逻辑的系统,这些系统承载着核心业务逻辑,几乎每个需求都和这些核心业务有关,这些核心业务业务逻辑冗长,...
2022-06-17 16:55:58 528浏览 0点赞 0回复 0收藏
构建了一个LiteflowConfig,传入xml的路径,然后构建FlowExecutor,最后调用FlowExecutor的execute2Resp,传入需要执行的业务流程名字chain1,就是xml中配置的,执行业务流程。结果如果业务变动,现在不需要执行B流程了,那么直接修改规则文件就行了,如图。运行结果这里发现B就没执行了。2)SpringBoot环境下引入pom依赖<dependency><groupId>com.yomahub<groupId><artifactId>liteflowspringbootstarter<artifactId><version>...
2022-06-17 16:55:52 1429浏览 0点赞 0回复 0收藏
三、LiteFlow核心组件讲解讲解核心组件的时候如果有什么不是太明白的,可以继续往下看,后面会有源码解析。下图为LiteFlow整体架构图1)Parser这个组件的作用就是用来解析流程配置的规则,也就是将你配置的规则文件解析成Java代码来运行。支持的文件格式有xml、json、yaml,其实不论是什么格式,只是形式的不同,用户可根据自身配置的习惯来选择规则文件的格式。同时,规则文件的存储目前官方支持基于zk或者本地文件的形式,同...
2022-06-17 16:55:43 215浏览 0点赞 0回复 0收藏
4)SlotSlot可以理解为业务的上下文,在一个业务流程中,这个Slot是共享的。Slot有个默认的实现DefaultSlot,DefaultSlot虽然可以用,但是在实际业务中,用这个会存在大量的弱类型,存取数据的时候都要进行强转,颇为不方便。所以官方建议自己去实现自己的Slot,可以继承AbsSlot。5)DataBus用来管理Slot的,从这里面可以获取当前业务流程执行的Slot。四、LiteFlow源码探究说完核心的组件,接下来就来剖析一下源码,来看一看Lit...
2022-06-17 16:55:32 182浏览 0点赞 0回复 0收藏
分割完之后,就会遍历每个路径,然后判断文件的格式,比如xml、json、yaml,然后根据文件格式找到对应的FlowParser。随后根据liteflowConfig.isSupportMultipleType()判断是不是支持多类型的,什么叫多类型,就是指规则文件配置了多个并且文件的格式不同,如果支持的话,需要每个规则文件单独去解析,如果不支持,那就说明文件的格式一定是相同的,相同可以在最后统一解析,解析是通过调用FlowParser的parseMain来解析的。剖析...
2022-06-17 16:55:19 216浏览 0点赞 0回复 0收藏
接下来就会继续遍历每个Document,也就是每个xml,然后拿到解析<nodes><nodes>中的每个<node><node>标签,拿出每个node标签中的属性,通过LiteFlowNodeBuilder构建Node,然后放入到FlowBus中,至于如何放入到FlowBus中,可以看一下LiteFlowNodeBuilder的build方法的实现。解析完Node之后,接下来就是解析<chain>标签,拿到每一个<chain>标签对应的Element之后,调用parseOneChain来解析<chain>标签的内容。parseOneChain方法,...
2022-06-17 16:55:12 206浏览 0点赞 0回复 0收藏
首先从DataBus中获取一个Slot,也就是当前业务执行的上下文。之后从FlowBus中获取需要执行的Chain,最后分别调用了Chain的executePre、execute、executeFinally方法,其实不用看也知道这些方法干了什么,其实就是调用不同的Condition中Node方法。executePre和executeFinally方法这两个方法最后调用的是同一个方法,就是分别找到PreCondition和FinallyCondition,取出里面的Node节点,执行excute方法。这里有重点说明一下,其实...
2022-06-17 16:55:07 177浏览 0点赞 0回复 0收藏
大家好,我是三友,今天不卷技术,来给大家分享一款防沉迷撸码的插件。一、前言身为一个热爱撸码的社会良好青年,不知道大家有没有跟我一样,一旦开始撸码,总会忘记时间,无意间就会导致长时间久坐,并且不会去主动去喝水,总是等口渴了才会去喝水。长此以往,可能会导致出现腰酸背痛等身体上的一些小毛病。我以前也尝试通过手环或者手表来提醒自己去改变这种状态,但是效果不明显,很容易忽略手环或者手表的提醒。于是,我找...
2022-06-17 16:54:57 202浏览 0点赞 0回复 0收藏
大家好,我是三友。今天跟大家聊一聊无论是在工作中常用还是在面试中常问的线程池,通过画图的方式来彻底弄懂线程池的工作原理,以及在实际项目中该如何自定义适合业务的线程池。一、什么是线程池线程池其实是一种池化的技术的实现,池化技术的核心思想其实就是实现资源的一个复用,避免资源的重复创建和销毁带来的性能开销。在线程池中,线程池可以管理一堆线程,让线程执行完任务之后不会进行销毁,而是继续去处理其它线程已...
2022-06-17 16:51:10 434浏览 0点赞 0回复 0收藏
当任务执行完之后,线程不会退出,而是会去从阻塞队列中获取任务,如下图接下来如果又提交了一个任务,也会按照上述的步骤,去判断是否小于核心线程数,如果小于,还是会创建线程来执行任务,执行完之后也会从阻塞队列中获取任务。这里有个细节,就是提交任务的时候,就算有线程池里的线程从阻塞队列中获取不到任务,如果线程池里的线程数还是小于核心线程数,那么依然会继续创建线程,而不是复用已有的线程。如果线程池里的线...
2022-06-17 16:51:00 151浏览 0点赞 0回复 0收藏