java-场景题

1、项目中的分布式锁

  • redis分布式锁:
    • 获取锁:SETNX
      • 为避免死锁设置过期时间()
      • key过期,业务却未处理完
        • 在锁将要过期的时候,如果服务还没有处理完业务,那么将这个锁再续一段时间。比如设置key在10s后过期,那么再开启一个守护线程,在第8s的时候检测服务是否处理完,如果没有,则将这个key再续10s后过期。
        • Redisson已实现,这个自动续时的我们称其为”看门狗”。
    • 释放锁:del
    • SETNX底层原理
      • Redis的SETNX命令底层原理是通过单线程模型和事务支持来实现原子性操作。当客户端发送SETNX命令到Redis服务器时,Redis会将该命令加入到命令队列中进行排队。当Redis从队列中取出该命令时,先检查指定的key是否已经存在,如果不存在则使用SETNX命令为其设置新值,并返回1表示设置成功;如果key已经存在,则不执行任何操作并返回0表示设置失败。这个过程是原子性的,可以保证在并发环境下同一时刻只有一个客户端能够成功地为一个key设定值。
    • 项目中具体实现
      • 加锁
        • 尝试获取锁
          //NX:表示仅当键不存在时才设置该键。这是实现锁的关键,因为它确保了多个客户端不会同时获取到锁。
          //PX:这个选项用于设置键的过期时间,单位是毫秒。这个过期时间是为了防止因为某些原因(如程序崩溃)导致锁无法被释放,从而发生死锁的情况。当锁到达过期时间后,Redis 会自动删除这个键,这样其他客户端就可以尝试获取锁了。
          redisTemplate.opsForValue().set(key, value, "NX", "PX", expire);
          
      • 释放锁:
        //释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,
        //此时有可能已经被另外一个线程持有锁,所以不能直接删除
        //使用lua脚本删除redis中匹配value的key
        
        /**
        * 解锁脚本
        */
        "if redis.call(\"get\",KEYS[1]) == ARGV[1] " +
        "then " +
        " redis.call(\"del\",KEYS[1]) " +
        "else " +
        " return 0 " +
        "end ";
  • zk分布式锁:
    • zookeeper就是通过临时节点和节点有序来实现分布式锁的。

      • 每个获取锁的线程会在zk创建一个临时有序的节点。

      • 节点创建成功后,判断当前线程创建的节点的序号是否是最小的。

      • 如果序号是最小的,那么获取锁成功。

        • 如果序号不是最小的,则对自己创建节点的前一节点进行监听。如果前一个节点被删了(锁被释放了),那么就会唤醒当前节点,成功获取锁。

2、分布式事务

  • CAP
    • CAP 模型是说,在一个分布式系统里面,不可能同时满足三个点
    • 2
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

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

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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值