相信对于朋友们来说,锁这个东西已经非常熟悉了,在说分布式锁之前,我们来聊聊单体应用时候的本地锁,这个锁很多小伙伴都会用
✔本地锁
我们在开发单体应用的时候,为了保证多个线程并发访问公共资源的时候,期望在同一个时间只能有一个线程去访问资源,且在这个线程访问资源结束之后,其他的线程才可以访问这块资源
这个时候会使用到锁机制,一般根据不同的场景会使用到互斥锁,读写锁,自旋锁等等
我们还知道使用锁是会影响效率的
- 例如如果互斥锁如果拿不到,那么会死等,这很浪费资源
- 自旋锁如果拿不到,则会在原地自旋,一会来问一下,一会又来问一下,效率会受影响
因此还会想办法去实现原子操作,不需要加锁的情况下,保证多个线程同步
这些方式都是属于本地锁,属于在同一个进程内可以使用的锁,目的是能够控制多线程 并发 访问资源
可随着时代的发展,单体应用逐渐演变成微服务架构的时候,发现使用进程里面的本地锁已经不适用了,没有办法满足我们的需求了,因此为了解决多进程并发问题,引入了分布式锁
为什么说没法满足我们需求呢?
举例时刻
例1
我们有一个全局变量 sum = 0,此时的应用程序中有两个线程,分别循环 50 次,每一次循环都是对 sum 进行 +1 的操作,我们知道,这种情况,我们需要使用本地锁例如互斥锁对 sum 加锁就可以实现,程序运行完毕后, 输出的 sum 为 100 ,这个没有毛病
例2
那么如果此时场景换成有有两个应用程序,分别需要去操作第三方资源中的 sum,还是分别操作 50 次,每操作一次即对 sum 进行 +1 操作
那么这个时候,我们在每个应用中进行加锁还有意义吗?
并没有意义,因为此处的 第三方资源,并不单独属于任何一个应用进程
就像例1 中, sum 全局变量的资源,并不单独属于某一个线程一样,因此,对于例2,就需要使用分布式锁了
什么是分布式锁?
那么具体分布式锁到底是个啥玩意儿?
他自然他也是锁,只不过是用于控制多进程之间 并发的
他是可以跨微服务,跨 虚拟机 的一种锁机制,上述的本地锁就完全做不到
那么还是上述的例 2,我们就这样使用分布式锁来进行处理
可以看到,使用分布式锁,和使用本地锁,其实思想都是一样的,都是为了控制程序的 并发 访问资源
都是属于君子锁,作为君子访问资源之前,先去看看能不能拿到锁,不能坏了规矩,要是坏了这个规矩,那么程序运行就会出问题
只不过本地锁是对应控制同一个进程内的多个线程并发
而分布式锁是对于多个进程 并发
✔分布式锁有哪些特点呢?
- 互斥
既然是说,最基本的互斥功能,必须得有,不能忘本
- ✔ 锁有超时机制,可以防止死锁
对于分布式锁来说,为了避免异常未被释放,会对所加入一个超时机制
例如进程 A 加锁,但是自己忘记释放锁,或者是因为进程 A 因为异常挂掉,最终导致没有释放锁,这个时候,锁到了超时时间,自动就会释放
- ✔ 可重入
一个进程加了锁,这个进程仍然是可以再次获取这个锁的,例如对分布式锁不断的续期,不断的设置过期时间
可是这里如果是对于本地锁,一个线程加了锁,如果再次加锁,那么就死锁了
- 可以高性能的取锁和加锁
- ✔高可用
从上述我们可以看到引入的分布式锁,实际上不是进程内部的资源,可以理解为他是一个第三方的资源,是一个中间件
自然使用这些中间件中来实现所的话,一般会使用集群,集群自然会去实现自己的高可用机制,如果某些节点出现了异常,自身提供出来的机制,外部程序仍然可以使用
此处提到的中间件一般都有这些:
- Redis
- Etcd
- Mysql
- Zookeeper
每一个组件去实现分布式锁的原理和机制是不一样的,但是达到的目的是一样的, 都是为了控制多进程并发。
- ✔分布式锁需要是非阻塞的
某个进程如果获取分布式锁,发现拿不到,则会返回 false , 这个进程就会去处理自己拿不到锁的逻辑,进程不会因为没有拿到锁而阻塞
总结
那么看到这里,能否回答标题的问题呢?
- 什么是分布式锁?
他是可以跨微服务,跨 虚拟机 的一种锁机制
- 分布式锁解决了什么问题?
他解决了在分布式系统中,访问共享资源的问题
感谢阅读,欢迎交流,点个赞,关注一波 再走吧
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~
文中提到的技术点,感兴趣的可以查看这些文章: