分布式锁简单真实案例

前段时间做小程序水运头条时,有个投票的功能需求,每个人一天只能对自己比较满意的小视频投一次票,本来我三下五除二就写完了,觉得大事告吉.去测试环境测试也很OK,本以为就会想往常以后就没事了.结果线上进行投票时,后台监控某些用户同一天竟然投了两票或多票,这时我领导提醒我,可能是用户连续点击了两下投票按钮(尽管前端可以在点击第一次时就将按钮置灰,但是为了防止别人恶意调用接口,后台还是得坐相应的控制),导致请求并发了.而线上又是多个服务器,负载均衡将不同的请求分发到了不同的机器进行投票.所以这时需要用分布式锁去解决这个问题.现在假设该用户在n1这台服务器第一次去投票了,这时会根据用户ID和活动ID给该用户一把锁,而恰巧的是该用户在n2这台服务器第二次去投票了,因为这把锁给n1这台服务器的该用户给占用着,所以n2这台服务器的该用户只能等待着.等n1这台服务器的该用户进行了投票,而n2这台服务器的该用户会去看有没有投过票了,如果投过票了,就不会去投票了.如果不加分布式锁的话,多次请求又是同一时间间隔发的,可能会在多台机器上差不多时间执行,这时判断有没有投过票了,都会认会没投过票了,程序都会往下面一直走,直到成功,所以这就是一个用户一天可以投递多票的原因.

一、什么是分布式锁?

要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁、进程锁。

线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段。线程锁只在同一JVM中有效果,因为线程锁的实现在根本上是依靠线程之间共享内存实现的,比如synchronized是共享对象头,显示锁Lock是共享某个变量(state)。

进程锁:为了控制同一操作系统中多个进程访问某个共享资源,因为进程具有独立性,各个进程无法访问其他进程的资源,因此无法通过synchronized等线程锁实现进程锁。

分布式锁:当多个进程不在同一个系统中,用分布式锁控制多个进程对资源的访问。

 

二、分布式锁的使用场景。

线程间并发问题和进程间并发问题都是可以通过分布式锁解决的,但是强烈不建议这样做!因为采用分布式锁解决这些小问题是非常消耗资源的!分布式锁应该用来解决分布式情况下的多进程并发问题才是最合适的。

有这样一个情境,线程A和线程B都共享某个变量X。

如果是单机情况下(单JVM),线程之间共享内存,只要使用线程锁就可以解决并发问题。

如果是分布式情况下(多JVM),线程A和线程B很可能不是在同一JVM中,这样线程锁就无法起到作用了,这时候就要用到分布式锁来解决。

三、分布式锁的实现(Hazalcast)

这里就以Hazalcast的分布式锁为例.(官方地址:https://hazelcast.org)

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值