一、分布式锁的原理

前言:

  随着互联网的快速发展,尤其是电商项目等大型项目越来越火,传统的单机项目已经不能满足业务的需求,在这种情况下出现了分布式、集群以及微服务的概念,随着这些新生的概念的出现同时伴随了一系列开发中的问题,下面来看一下这其中之一的分布式锁。

一、什么是分布式锁:

  在这里为了引出分布式锁先来看一个案例,例如在一个大型的电商项目中传统的单击项目会对服务器造成超负荷的压力,而在这时我们往往会采用集群的方式来分担服务器的压力,比如我们搭建了二十多台负责用户支付下订单,同时每一台服务器都存在一个定时任务用来从队列中获取订单进行操作,那么这个时候问题就出现了。

  例如A服务器在操作一条订单数据,还没有操作完没来得及修改订单状态,这时B服务器同样查询到了相同的数据进行了操作,这样就会出现严重的脏数据,导致数据的不准确性,这是在支付系统中严重不允许出现的。

  而为了保证多台服务器原子性的执行任务,而为每台服务器加一个锁,以确保在某个服务器操作其中一条订单数据时,其他服务器处于阻塞的状态,这样的锁我理解为分布式锁。

二、为什么需要分布式锁:

  通过上面的例子我们可以知道,再从在多台服务器集群的情况下会出现例如多线程一样的问题,而在传统的单机服务器的时候,出现线程安全问题我们都是通过加锁来保证代码的原子性操作,避免线程安全问题。

  但我们都知道传统我们解决多线程问题加锁,这个锁其实是在内存中的一个标记,谁拿到了这个标记谁就拥有代码的执行权,但是在集群环境下每一台服务器都拥有一个jvm,且都是一个 不同的进程,他们之间的内存是不共享的,要想解决不同服务器之间类似多线程的问题,传统加锁的方式使无法实现的。

  这种时候我们就需分布式锁 ,而分布式锁就是用来解决不同进程之间的互斥问题。

三、分布式锁的解决方案:

  上面我们说了传统的线程锁如synchronied或lock锁是针对同一个jvm进程内的多个线程才有效的,因为锁的本质就是内存中的一个标记,记录获取锁的线程是谁,且这个标记是所有线程可见的。

  然而在这里我们启动的是多个服务,就是多个jvm、多个进程,这显然他们之间内存是独立不共享的,也就导致了内存中的锁是不共享的,每个jvm进程都有自己的锁,自然我们用加锁这种方式是无法解决线程之间的互斥的。

  我们分析了为什么加锁无法解决多个服务器之间进程互斥的原因,就是不同服务器拥有各自的锁,且锁是其他服务器不可见的,从而导致的问题,那么我们只要保证多个服务器之间拥有同一把锁,保证这把锁是可见的,不久可以解决上面的问题了吗,而这就是分布式锁结局不同进程之间互斥的原理。

四、分布式锁的基本原理:

  上面我们分析得出了解决不同进程之间互斥的方式,就是我们定义一个锁让所有的进程可见,而在java中传统额锁是无法实现的这就需要我们自己来实现这么一个所,那么我们来看一下要想定义一个分布式锁,要满足那些基本需求:

  多进程可见(必须):这个使我们上面一直强调的,如果多进程不可见就无法实现分布式的效果;

  互斥(必须):同一时刻只能有一个进程获的锁,执行任务后释放锁;

  可重入(可选):同一个任务再次获取锁时,不会被锁死;

  阻塞锁(可选):获取失败时具备重试机制,尝试再次获取锁;

  性能好(可选):效率高,能够应对高并发场景;

  高可用(可选):避免服务宕机或处理好宕机的补救措施;

  

posted @ 2019-09-17 15:55  は問わない  阅读(293)  评论(0编辑  收藏  举报