分布式共享锁

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 11.1 需求描述在我们自己的分布式业务系统中,可能会存在某种资源,需要被整个系统的各台服务器共享访问,但是只允许一台服务器同时访问 11.2 设计思路  11.3 代码开发 public class DistributedClientMy {      // 超时时间      private static

11.1 需求描述

在我们自己的分布式业务系统中,可能会存在某种资源,需要被整个系统的各台服务器共享访问,但是只允许一台服务器同时访问

 

11.2 设计思路

 

11.3 代码开发

 

public class DistributedClientMy {

     // 超时时间

     private static final int SESSION_TIMEOUT = 5000;

     // zookeeper server列表

     private String hosts = "spark01:2181,spark02:2181,spark03:2181";

     private String groupNode = "locks";

     private String subNode = "sub";

     private boolean haveLock = false;

 

     private ZooKeeper zk;

     // 当前client创建的子节点

     private volatile String thisPath;

 

     /**

      * 连接zookeeper

      */

     public void connectZookeeper() throws Exception {

          zk = new ZooKeeper("spark01:2181", SESSION_TIMEOUT, new Watcher() {

               public void process(WatchedEvent event) {

                    try {

 

                         // 子节点发生变化

                         if (event.getType() == EventType.NodeChildrenChanged && event.getPath().equals("/" + groupNode)) {

                              // thisPath是否是列表中的最小节点

                              List<String> childrenNodes = zk.getChildren("/" + groupNode, true);

                              String thisNode = thisPath.substring(("/" + groupNode + "/").length());

                              // 排序

                              Collections.sort(childrenNodes);

                              if (childrenNodes.indexOf(thisNode) == 0) {

                                   doSomething();

                                   thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE,

                                             CreateMode.EPHEMERAL_SEQUENTIAL);

                              }

                         }

                    } catch (Exception e) {

                         e.printStackTrace();

                    }

               }

          });

 

          // 创建子节点

          thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE,

                    CreateMode.EPHEMERAL_SEQUENTIAL);

 

          // wait一小会, 让结果更清晰一些

          Thread.sleep(new Random().nextInt(1000));

 

          // 监听子节点的变化

          List<String> childrenNodes = zk.getChildren("/" + groupNode, true);

 

          // 列表中只有一个子节点, 那肯定就是thisPath, 说明client获得锁

          if (childrenNodes.size() == 1) {

               doSomething();

               thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE,

                         CreateMode.EPHEMERAL_SEQUENTIAL);

          }

     }

 

     /**

      * 共享资源的访问逻辑写在这个方法中

      */

     private void doSomething() throws Exception {

          try {

               System.out.println("gain lock: " + thisPath);

               Thread.sleep(2000);

               // do something

          } finally {

               System.out.println("finished: " + thisPath);

               // 将thisPath删除, 监听thisPath的client将获得通知

               // 相当于释放锁

               zk.delete(this.thisPath, -1);

          }

     }

 

     public static void main(String[] args) throws Exception {

          DistributedClientMy dl = new DistributedClientMy();

          dl.connectZookeeper();

          Thread.sleep(Long.MAX_VALUE);

     }

 

    

}

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
6天前
|
监控 安全 Apache
Apache ZooKeeper - 使用ZK实现分布式锁(非公平锁/公平锁/共享锁 )
Apache ZooKeeper - 使用ZK实现分布式锁(非公平锁/公平锁/共享锁 )
98 1
zookeeper实现分布式共享锁
zookeeper实现分布式共享锁
74 0
|
6天前
|
NoSQL Java 关系型数据库
【Redis系列笔记】分布式锁
分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路
135 2
|
6天前
|
NoSQL Java Redis
redis分布式锁
redis分布式锁
|
6天前
|
存储 监控 NoSQL
【Redis】分布式锁及其他常见问题
【Redis】分布式锁及其他常见问题
32 0
|
6天前
|
NoSQL Java Redis
【Redis】Redis实现分布式锁
【Redis】Redis实现分布式锁
8 0
|
6天前
|
监控 NoSQL 算法
探秘Redis分布式锁:实战与注意事项
本文介绍了Redis分区容错中的分布式锁概念,包括利用Watch实现乐观锁和使用setnx防止库存超卖。乐观锁通过Watch命令监控键值变化,在事务中执行修改,若键值被改变则事务失败。Java代码示例展示了具体实现。setnx命令用于库存操作,确保无超卖,通过设置锁并检查库存来更新。文章还讨论了分布式锁存在的问题,如客户端阻塞、时钟漂移和单点故障,并提出了RedLock算法来提高可靠性。Redisson作为生产环境的分布式锁实现,提供了可重入锁、读写锁等高级功能。最后,文章对比了Redis、Zookeeper和etcd的分布式锁特性。
141 16
探秘Redis分布式锁:实战与注意事项
|
6天前
|
NoSQL Java 大数据
介绍redis分布式锁
分布式锁是解决多进程在分布式环境中争夺资源的问题,与本地锁相似但适用于不同进程。以Redis为例,通过`setIfAbsent`实现占锁,加锁同时设置过期时间避免死锁。然而,获取锁与设置过期时间非原子性可能导致并发问题,解决方案是使用`setIfAbsent`的超时参数。此外,释放锁前需验证归属,防止误删他人锁,可借助Lua脚本确保原子性。实际应用中还有锁续期、重试机制等复杂问题,现成解决方案如RedisLockRegistry和Redisson。