最近一直在学习RabbitMQ,但是不知如何在实际业务中撸出它的功效,最近刚好看到一篇相关文章,有一些心得,想和小伙伴们分享一下!
一篇文章教你搞定递归单链表反转
关于单链表反转,阿粉以前写过一篇文章,是用迭代法实现的,还有一种方法是使用递归来实现的,阿粉一直没敢写,因为害怕讲不清楚。但是不能因为害怕讲不清楚就不写了,对不对。
所以这篇文章来使用递归来实现一下,并且尝试将里面的细节一一剖出来,不废话。
mybatis系列之mybatis源码讲解
hello~各位读者好,我是鸭血粉丝(大家可以称呼我为「阿粉」)。今天,我们继续
mybatis
源码讲解的第三篇文章。
1.上期回顾
首先,我们还是回顾一下上篇文件的类容。毕竟离上次讲 mybatis
还是过去了很久,汗~。
还是先看下这个测试类,大家还有印象吗:
1 |
|
上篇源码分析讲了 SqlSessionFactory
构建的过程。这次,我们来了解下 SqlSession
。
2.SqlSession
2.1 什么是 SqlSession
SqlSession
是我们自己的程序与数据库的一次会话。它是线程不安全的,所以我们在请求开始的时候创建一个SqlSession 对象,在请求结束或者说方法执行完毕的时候要及时关闭它。
阿粉在这里举例简单的例子说明一下一次会话
。比如我们打电话,电话接通,通了之后一般情况下都是你说完一件事,对方在回答,然后你在说,对方在回答,直到你事情说完了挂断电话,这个过程就相当于一次会话。在我们程序中也是一样的道理,先和数据库建立一个连接,然后发送sql,数据库执行完成之后会返回结果,然后又可以发送sql,直到方法执行完毕,关闭连接,这就是一次会话。
然后阿粉在补充一点,mysql
的通信方式是半双工,被动的执行请求。在一次会话中,必须等 mysql
返回结果才能执行下一个sql操作,相当于同步。
2.2 创建SqlSession
的过程
我们来看上面代码的这段 SqlSession session = sqlSessionFactory.openSession();
,然后上次文章中阿粉带着大家了解了,build
方法返回的是 DefaultSqlSessionFactory
对象。
1 |
|
所以,我们在 DefaultSqlSessionFactory
类中找到 openSession
方法。
1 |
|
然后 openSessionFromDataSource
方法:
1 |
|
我们一句一句的来看下,首先是 final Environment environment = configuration.getEnvironment();
Environment
这个还有印象吗?阿粉第一次讲 mybatis.xml
一级标签的时候有说哦,忘了的话阿粉在带着大家回忆一下哦。
1 |
|
这个对象里面就是存放的事物的配置和数据源的配置信息。然后后面两句就清楚了呗,先创建一个事物工厂,事物工厂通过数据源信息创建事物对象,这里又用到了工厂模式。这个就不详细讲了,因为和Spring整合后,这些事情就不是 mybatis
做了。
我们看下面一句:Executor executor = configuration.newExecutor(tx, execType),这句是创建Executor
实例。先来了解一下Executor
:
Executor
是个接口,执行器的抽象对象,有3种基本类型:SIMPLE、BATCH、REUSE,默认是SIMPLE。然后看下这三个的区别:
- SimpleExecutor:每执行一次update 或select,就开启一个Statement 对象,用完立刻关闭Statement 对象。
- ReuseExecutor:执行update 或select,以sql 作为key 查找Statement 对象,存在就使用,不存在就创建,用完后,不关闭Statement 对象,而是放置于Map 内,供下一次使用。简言之,就是重复使用Statement 对象。
- BatchExecutor:执行update时将所有sql 都添加到批处理中(addBatch()),等待统一执行。它缓存了多个Statement 对象,每个Statement 对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC 批处理相同。
然后继续源码,看下newExecutor
方法
1 |
|
前面的if
判断就是根据传入的类型来创建Executor
,看下后面的判断:是否开启缓存,这里使用了装饰器模式,这个类(CachingExecutor)就是二级缓存的实现。
然后执行器(Executor
)创建后,就会创建一个DefaultSqlSession
对象。
4.总结
这次主要是分享创建 SqlSession
的源码流程,不知道阿粉有没有讲清楚,因为源码比较多,阿粉都调整文章好几次。有兴趣的同学可以跟着阿粉的思路走一遍源码,肯定还是有收获的。
Markdown 实用语法解析
阿粉总觉得之前自己写的文档很丑,有没有什么好的、先进的文档编写格式呢?网上一搜有个东西叫 markdown 让阿粉觉得不得了啊,赶紧学了一波~真刺激。
Markdown 是什么
Markdown
是一种轻量级
标记语言,是一种方便记忆、书写的纯文本标记语言。目前各大知识内容平台例如知乎,简书都支持用户使用 Markdown 进行快速编辑,他同时也是全球最大的技术分享网站 GitHub 和技术问答网站 StackOverFlow 的书写格式。
从零搭建一个属于自己的个人网站
很多小伙伴私信我,问我怎么弄一个个人博客系统,之前其实也聊过,不过没关系,今天我们再来详细的说一说。
网传阿里工程师因为 3.25 绩效植入脚本,使得淘宝弹窗一天未修复!【辟谣】
2020 年 3 月 25 日,一个索然无味的的星期三,阿粉日常打开手机淘宝,看看有什么需要买的。然后阿粉就看到了下面的提示:
项目中用到了Redis分布式锁,我了解了一下背后的原理
前言
以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存。可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单。在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情况是这样的:
该项目在某金融平台中负责某块业务,是一个分布式系统,线上大概跑着10个左右的实例。其中有一个步骤需要用户支付一定的费用,Redis分布式锁在其中大概处于这么一个位置:
可以看到在上分布式锁之后,系统做了两个查询校验,然后向数据库中插入了一条订单记录,接着才解锁进入支付流程。
从业务的角度考虑分布式锁是好理解的,它保证了查询及插入数据整个流程的原子性,防止查询校验的时候查到脏数据,使得支付前订单信息落表的操作串行化执行。
尽管从业务上来说很好理解,但使用Redis作为分布式锁对我来说是个新知识,阿粉打算结合项目中的代码,深挖一下这个知识点。
正文
1. 为什么要使用分布式锁
在实际项目中见过分布式锁后,就不难理解为什么要使用分布式锁了:总结来说就是分布式系统要访问共享资源,为了避免并发访问资源带来错误,我们为共享资源添加一把锁,让各个访问互斥,保证并发访问的安全性,这就是使用分布式锁的原因。
2. Redis中分布式锁的实现
redis中使用分布式锁很简单,只要使用setnx指令对某个key上锁就行:
1 |
|
当某个key没有被占用的时候,setnx指令会返回1,否则返回0,这就是Redis中分布式锁的使用原理。
当然我们还可以在上锁之后使用expire指令给锁设置过期时间。
看到这里你可能会有疑问,如果我们的程序流程不使用指令解锁,靠redis设置时间过期来解锁,貌似会出问题。假如我们的服务进程在执行setnx之后和执行expire指令之前挂掉了,那这个锁岂不是永远都不能被释放?
没错,这确实是个问题,当时人们在Redis的开源社区提出了一堆解决方案专门来解决这个问题,可实现方式都极为复杂。后来Redis的作者在Redis 2.8版本中加入了set指令的扩展参数,使得setnx指令和expire指令能够同时执行,具体使用像下面这个样子:
1 |
|
从此以后,Redis成为了分布式锁的宠儿。
3. 分布式锁在Redis集群中遇到的麻烦
在学习了Redis中分布式锁的使用后,很快我们便发现了新的问题。在企业中,Redis基本上都是集群部署的,集群部署避免不了要面对某个节点宕机的问题。
我们考虑这么一种情况:假设我们在redis的主节点上添加了一把分布式锁,不幸的是主节点挂掉了,而且主节点上的锁还没有同步到从节点上,如果此时有客户端来请求获得同一把锁,那么它将顺利地获得锁,之前那把锁会被无情地忽视掉,这就是分布式锁在Redis集群中遇到的麻烦。
Redis的作者为了解决这个问题提出了一个叫Redlock的算法,它的原理是这样的:当上锁的时候,把set指令发送给过半的节点,只要过半的锁set成功,就认为这次加锁成功;当解锁的时候,会向所有的节点发送del指令。
从这个算法的原理可以看出,由于Redlock需要同时对多个节点进行读写,因此使用Redlock加分布式锁的性能要比单机Redis低很多。因为主从复制出纰漏的概率极低,所以如果对分布式加锁过程有一定的容错率的话,可以考虑直接使用set指令;如果追求高可用性,可以考虑使用Redlock算法。
当然,高可用性的分布式锁不只有Redis的Redlock,我们还可以用zookeeper或者支持事务的数据库做分布式锁。
简述zookeeper的分布式锁原理:假设zk用某个节点作为分布式锁,当不同的客户端到zk竞争这把锁的时候,zk会按顺序给不同的客户端创建一个子节点,挂在作为分布式锁的节点下面。假设第一个来到的客户端为A,第二个来到的是B,分布式节点下挂的第一个节点就是A,B紧跟着A,且B会监听着A的生命状态,当A释放锁后A会被删除,这时B监听到A被删除,B接能上位获得分布式锁了。
在公司的项目中,虽然Redis是以集群的方式部署的,但还是使用最基本的set指令获取分布式锁,因为这种方式的性能远远高于Redlock算法,也高于zk,数据库等分布式锁实现方式。
虽然在高性能与低概率的错误中选择了高性能,但项目中还是做了其他工作对错误情况进行兜底的,比如在公司的项目中对主从复制时的错误情况会抛出异常,然后根据异常会进行一些重试的操作。
总结
这次对Redis分布式锁的探索算是加深了自己对Redis的理解,但我知道Redis的用处还远远不止分布式锁和缓存,留着后面继续探索吧。
想问一下各位大佬,走 Java 后台路线,前端要学到什么程度才 OK?
大家好,我是鸭血粉丝,不知道作为后台开发人员,你有没有过类似文章标题的疑惑呢?
如果让我贡献第一次,我会选择这里
我们人生中会有许许多多的第一次,第一次看完一本书,第一次看一部电影,第一次谈恋爱,第一次。。。(自行脑补)
但是,如果让我选择我的第一次,我会选择这里,这里是哪里?当然是 Java极客技术
。
熟悉我们的小伙伴们可能知道我们是做什么的,不知道的小伙伴们我再重复一下,我们一个原创
、高质量
、技术平台
,我们致力于为 Java 程序员提供优质的学习平台,在这里,你可以分享技术。
- 你可以分享生活感悟,读书笔记
- 你可以学习到精心为你准备的设计模式教程
- 我们还为你准备了
江南一点雨
松哥的 SpringBoot 全套系列视频,供你学习
就只是这一套资料都要比入场券贵多了
。
-
我们提供的优质回答,你仔仔细细研究一个分享都能让你值回票价,我们从创立开始就秉承了提供一个学习交流的平台的理念,我们是赚不到什么钱的,这个费用是我希望你加入进来能认真对待这件事情的一个凭证,而且这个钱我相信大部分程序员不到一个小时就赚到了。
-
我们会不定期有作业,题目都比较简单,优秀回答会获得星主和合伙人的奖励,让你有动力去思考问题,涛涛交流
- 星球的朋友们活跃度比较高,分享的内容都是
杠杠的
我们大家知道现在知识付费
将会是以后发展的趋势了,随便一篇文章都要几十、一套教程都要上百、上千的,我们的价格很亲民了,只需要 66
元。我这里想问一下,有哪个星球只有 66 元就可以加入的?
学习的金字塔模型分为被动接受和主动获取,而主动获取往往是效率比较高的学习方式,在当今信息量爆炸的年代,如何高效率的学习很关键,所以我们在自己学习的同时,一定要多分享,多交流,我们的知识星球
其实就是这样一个平台。
拿一句最近流行的一句话说就是你的圈子决定了你的阶层,赶紧来和我们一起成长吧,我们会保证你的付出,物超所值的。
干开发为什么你发现有人比你工资高却什么代码都不写呢?
hello~各位读者好,我是鸭血粉丝(大家可以称呼我为「阿粉」),在这个特殊的日子里,大家要注意安全,尽量不要出门,无聊的话,就像阿粉一样,把时间愉快的花在学习上吧。
计算机基础知识总结
阿粉一个后端程序员如何被公司逼的开始写前端代码!奉劝各位最好选择前后端分离的公司。
hello~各位读者好,我是鸭血粉丝(大家可以称呼我为「阿粉」),在特殊的日子里,大家要注意安全,尽量不要出门,无聊的话,就像阿粉一样,把时间愉快的花在学习上吧。
为什么Mysql的常用引擎都默认使用B+树作为索引?
tomcat也终于出现漏洞了,阿粉问你,线上版本更换了么?
hello~各位读者好,我是鸭血粉丝(大家可以称呼我为「阿粉」),在这个特殊的日子里,大家要注意安全,尽量不要出门,无聊的话,就像阿粉一样,把时间愉快的花在学习上吧。
如何学好 java 这门技术
对于初次接触 Java 的朋友,想必一定很迷茫,想知道 Java 具体能干啥,如何掌握好 Java 这么技术,如何运用好 Java 技术进行项目开发等疑惑!
还在使用集合类完成这些功能?不妨来看看 Guava 集合类!!!
日常开发中,阿粉经常需要用到 Java 提供集合类完成各种需求。Java 集合类虽然非常强大实用,但是提供功能还是有点薄弱。
从页面输入网址,回车到显示内容,这中间到底经历了什么
疫情期间全家被隔离,而我辛苦一年却被无故裁员
大家好,我是鸭血粉丝,今天不聊技术,我们聊聊裁员的事情。
最近阿粉的一个朋友跟阿粉抱怨,说自己被裁员了,而且去年的年终绩效考核被领导打成了最低等,没有拿到年终奖,想想自己辛苦一年最后却落得这个下场,实在是难受。为了避免泄露敏感信息,阿粉就称这个朋友为小 A 了。
听到这个消息阿粉还是很惊讶的,因为小 A 平时工作很认真负责,经常半夜还在加班,节假日就更不用说了,时常加班。为什么绩效考核会是最低等,而且还会被裁员呢?更何况还是在现在这个时期,简直是祸不单行。
HTTPDNS 协议了解吗?进来了解下
说起 DNS 协议,相信大家都能说出来几句,不是很陌生。
一文带你了解分布式网关 Kong
大家好,我是鸭血粉丝,想起来之前生产发生的事故,阿粉我的内心到现在都还很忐忑不安,今天我们来学习一个 Kong 以及跟你们聊聊做好网关限流控制的重要性。