V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
SkyLine7
V2EX  ›  Java

项目中什么场景需要用到分布式锁

  •  1
     
  •   SkyLine7 · 2020-12-22 10:25:49 +08:00 · 4568 次点击
    这是一个创建于 550 天前的主题,其中的信息可能已经有所发展或是发生改变。

    开发了 1 年多,一直做的是管理系统的 curd,没有用到过锁,没有接触过电商项目,想请教各位 v 友,锁是什么场景需要用到的?怎么判断一个方法要不要加锁?是加 jvm 锁还是分布式锁?

    第 1 条附言  ·  2020-12-22 13:05:31 +08:00
    希望大家说一些实际的例子
    第 2 条附言  ·  2020-12-22 13:25:14 +08:00
    看了大家的回答,我能不能这样理解:
    1.单机环境下 jvm 进程锁就能保证线程安全了,分布式环境需要用到分布式锁保证每个节点的原子性,
    2.加锁的原则就是看有没有共享资源被多个线程使用。
    43 条回复    2020-12-23 13:47:16 +08:00
    ahsjs
        1
    ahsjs  
       2020-12-22 10:29:43 +08:00
    有竞争的时候
    SkyLine7
        2
    SkyLine7  
    OP
       2020-12-22 10:33:30 +08:00
    @ahsjs 能说的明白些吗
    RedBeanIce
        3
    RedBeanIce  
       2020-12-22 10:35:39 +08:00   ❤️ 3
    多台服务器做同一件事情。要抢着用,
    那么用分布式锁,
    前面的人用完了你才可以进去,或者是前面的人用完了你就可以走了。

    简单的来说,你可以写一个项目,项目写一个定时任务,每天 10 点 34 分跑一次发一次右键,

    用两台服务器部署,不用分布式锁,那么你的定时任务可能会跑两次,但是实际上你只需要跑一次。用分布式锁锁上以后,你的代码只会跑一次。(简单应用)
    MinQ
        4
    MinQ  
       2020-12-22 10:37:24 +08:00   ❤️ 2
    一般来说分布式锁跟负载均衡是一起出现的,如果有多个机器在同一时间会去做一样的事情,就需要锁
    例如负载均衡的情况下给用户发短信,用户短时间内请求了多次,第一次如果没有锁的话可能数据库里的标识没有被修改为已发送就被第二次读取了,这样用户就会收到 N 条短信
    SkyLine7
        5
    SkyLine7  
    OP
       2020-12-22 10:39:37 +08:00
    @RedBeanIce 谢谢
    SkyLine7
        6
    SkyLine7  
    OP
       2020-12-22 10:39:48 +08:00
    @MinQ 谢谢
    carlclone
        7
    carlclone  
       2020-12-22 10:53:57 +08:00 via Android
    多台机器争抢一个任务的执行权
    redtea
        8
    redtea  
       2020-12-22 11:11:25 +08:00
    能用的都该用上,比如注册功能,需要先校验用户名是否存在才能插入数据库,单机用 synchronized 就能解决并发,但是有一天领导说要上负载均衡了,怎么办,等你再改代码加上分布式锁吗,这样子开发测试部署不知道要花多久的时间,本来复制拷贝一下就能部署的。
    SkyLine7
        9
    SkyLine7  
    OP
       2020-12-22 11:18:21 +08:00
    @redtea 老哥,意思是写操作都加上锁吗
    redtea
        10
    redtea  
       2020-12-22 11:28:42 +08:00
    @SkyLine7 如果并发调用一个接口有问题,就该考虑加上分布式锁。
    yisheyuanzhang
        11
    yisheyuanzhang  
       2020-12-22 11:30:14 +08:00
    集群环境用
    JVM 锁 synchronized 、Lockd 这些只对单个 jvm 环境内有效。
    只部署 1 台服务,jvm 锁能保证两个请求不并发处理
    如果同时部署多台服务,如果两个请求分别被发送到两个服务上,这时候 jvm 锁就不能限制了
    kiracyan
        12
    kiracyan  
       2020-12-22 11:40:10 +08:00
    分布式锁 = 锁 + 分布式应用可访问
    freebird1994
        13
    freebird1994  
       2020-12-22 11:54:06 +08:00 via Android
    最简单的幂等问题就可以用分布式所
    tesguest123
        14
    tesguest123  
       2020-12-22 11:58:15 +08:00 via iPhone
    面试的时候
    hwdef
        15
    hwdef  
       2020-12-22 12:35:45 +08:00
    可以了解一些分布式项目中的锁,,,比如 etcd,比如 k8s,都在什么情况下加锁。
    wudaye
        16
    wudaye  
       2020-12-22 13:01:39 +08:00 via Android
    竞争资源的时候。同一个事情同一时刻只能有一个执行者在做,那这个事情的执行权就是要竞争的独一份的资源
    SkyLine7
        17
    SkyLine7  
    OP
       2020-12-22 13:04:23 +08:00
    @freebird1994 好的,谢谢
    SkyLine7
        18
    SkyLine7  
    OP
       2020-12-22 13:04:45 +08:00
    @wudaye 老哥,能举个实际的例子吗
    SkyLine7
        19
    SkyLine7  
    OP
       2020-12-22 13:23:08 +08:00
    @hwdef 好的,谢谢
    catror
        20
    catror  
       2020-12-22 13:23:21 +08:00 via Android
    这是在准备面试题?
    锁是用来解决并发问题的,分布式锁自然是解决分布式系统中的并发问题。
    比如分布式限流、幂等处理…光知道场景感觉也不够,你要理解为什么会出现这样的场景。
    jorneyr
        21
    jorneyr  
       2020-12-22 13:38:27 +08:00
    我经历过的:
    1. 集群中视频、文档转换,同一个文件同时只有一个服务转,不要重复转,避免浪费资源
    2. 支持并行任务的作业系统,某个任务结束后,要修改所有后继任务的入度,执行可以开始执行的任务,也是用分布式锁保证同一个作业的原子性操作
    jorneyr
        22
    jorneyr  
       2020-12-22 13:42:55 +08:00
    再补充一点,视频和文档转换了个,前端会请求预览某个视频和文档,没有转好的时候会发一条消息到 MQ,消息的消费者收到消息后进行转换,这个过程会产生同一个文档有多个请求转换的消息,所以用分布式锁保证同一个文件在集群中只会有一个服务在进行转换,因为转换是一个耗时任务,期间不会知道有多少个转换的消息。
    hhyyd
        23
    hhyyd  
       2020-12-22 14:18:32 +08:00   ❤️ 1
    库存减扣、商品唯一编码生成、多系统从获取快递运单号
    zr8657
        24
    zr8657  
       2020-12-22 14:35:05 +08:00
    k8s 跑多份 pod,加锁自然要加分布式锁
    SkyLine7
        25
    SkyLine7  
    OP
       2020-12-22 14:44:11 +08:00
    @jorneyr 谢谢
    SkyLine7
        26
    SkyLine7  
    OP
       2020-12-22 14:44:28 +08:00
    @hhyyd 谢谢
    SkyLine7
        27
    SkyLine7  
    OP
       2020-12-22 14:44:51 +08:00
    @zr8657 我们还没用 k8s,谢谢
    SkyLine7
        28
    SkyLine7  
    OP
       2020-12-22 14:45:21 +08:00
    @catror 是呀 我现在连场景都很蒙蔽
    anonydmer
        29
    anonydmer  
       2020-12-22 14:58:02 +08:00
    楼主,虽然你只做了一年的 CRUD,但是系统中没有遇到那种只要是并发操作就可能带来的问题?不应该吧,还是你们把这种问题忽略了?
    leafre
        30
    leafre  
       2020-12-22 15:09:15 +08:00
    不要用分布式锁,串行化性能差,一般考虑其他解决方案
    chennqqi755
        31
    chennqqi755  
       2020-12-22 16:05:35 +08:00
    锁是解决资源竞争问题的,分布式锁就是解决分布式环境下多个程序竞争一个资源的问题。例如支付,购物,订单等共享独占资源
    SkyLine7
        32
    SkyLine7  
    OP
       2020-12-22 16:10:50 +08:00
    @anonydmer 忽略了 哎
    serical
        33
    serical  
       2020-12-22 17:18:35 +08:00
    比如微信支付提现, 一个商户账号 30 秒内只能让一个人提现
    qq1009479218
        34
    qq1009479218  
       2020-12-22 18:14:12 +08:00
    服务需要执行某个 job,但是服务被部署成多个实例(需要负载均衡嘛),但是这个 job 只能起一个线程去 run,就用到了所谓的分布式锁;多个线程需要去抢这个 job 去执行,就需要锁。在支持线程操作的语言里,锁就是锁,上升到服务层面(也就是加一层网络,线程分布在多机器上)就叫分布式锁了
    pisc
        35
    pisc  
       2020-12-22 19:42:00 +08:00 via Android
    这种基础问题。。。千言万语一句话:找本系统的书来看,而不是来这里问,这里一般只能获取到一些零碎“启发性”的知识,如果没有专门学习过,很容易犯“自以为知道”的错误
    mtrec
        36
    mtrec  
       2020-12-22 21:25:09 +08:00 via Android
    微服务用得多 比如商城商品上新 需要更新商品系统会员系统仓储系统优惠系统等 每个系统又有自己的数据库 这时候就要分布式锁保证所有系统的数据库事务一致性
    shanghai1998
        37
    shanghai1998  
       2020-12-22 21:31:41 +08:00
    喜欢拆系统的人,比如 会员系统、订单 系统、支付系统,用户购买商品获得积分这个流程 就需要分布式锁
    SkyLine7
        38
    SkyLine7  
    OP
       2020-12-23 13:45:59 +08:00
    @mtrec 谢谢
    SkyLine7
        39
    SkyLine7  
    OP
       2020-12-23 13:46:14 +08:00
    @qq1009479218 谢谢
    SkyLine7
        40
    SkyLine7  
    OP
       2020-12-23 13:46:30 +08:00
    @serical 谢谢
    SkyLine7
        41
    SkyLine7  
    OP
       2020-12-23 13:46:48 +08:00
    @pisc 好的,老哥
    SkyLine7
        42
    SkyLine7  
    OP
       2020-12-23 13:47:06 +08:00
    @mtrec 谢谢
    SkyLine7
        43
    SkyLine7  
    OP
       2020-12-23 13:47:16 +08:00
    @shanghai1998 谢谢
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2052 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:27 · PVG 00:27 · LAX 09:27 · JFK 12:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.