在 Java 中使用 ZooKeeper 实现分布式锁可按以下几步进行:
下载安装 ZooKeeper 3.4.13 ,参考 本机安装 ZooKeeper 集群 进行安装单机版 ZooKeeper,有必要的时候再安装集群
引入 Curator 的依赖,它实现了 ZooKeeper 的分布式锁
Java 测试程序
下载安装 参考 本机安装 ZooKeeper 集群
引入 Curator 的依赖 1 compile group: 'org.apache.curator' , name: 'curator-recipes' , version: '2.12.0'
注意: Curator 和 ZooKeeper 的版本需要对应,否则会报错
Curator 2.x.x
: compatible with both ZooKeeper 3.4.x and ZooKeeper 3.5.x
Curator 3.x.x
: compatible only with ZooKeeper 3.5.x and includes support for new features such as dynamic reconfiguration, etc.
Java 测试程序 官方文档: http://curator.apache.org/getting-started.html,先演示 Curator 连接 ZooKeeper 并使用分布式锁 InterProcessMutex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public static void testDistributedLock () throws Exception { CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181" , new ExponentialBackoffRetry(10000 , 3 )); client.start(); InterProcessMutex lock = new InterProcessMutex(client, "/ebag/lock" ); if (lock.acquire(10 , TimeUnit.SECONDS)) { try { System.out.println("Do something" ); } finally { lock.release(); } } client.close(); }
多线程测试分布式锁,结果 sn 是按顺序输出的,说明锁生效了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public static void testZooKeeperThread () { CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181" , new ExponentialBackoffRetry(10000 , 3 )); client.start(); List<Thread> threads = new LinkedList<>(); for (int i = 0 ; i < 100 ; ++i) { threads.add(new Thread(new ZooKeeperRunnable(client, "/ebag/lock" ))); } for (Thread thread : threads) { thread.start(); } } class ZooKeeperRunnable implements Runnable { public static int sn = 0 ; private InterProcessMutex lock; public ZooKeeperRunnable (CuratorFramework client, String path) { lock = new InterProcessMutex(client, path); } public void run () { try { if (lock.acquire(10 , TimeUnit.SECONDS)) { try { sn++; System.out.println(sn); } finally { lock.release(); } } } catch (Exception e) { e.printStackTrace(); } } }
提示: 上面的多线程是同一个 JVM 中的,可以很简单的修改为在多个 JVM 中运行,演示真正的分布式锁的效果,共享资源 sn 可以保存到 Redis,数据库等中。
ZooKeeper 常用命令
创建: create path data: create /foo "Hello"
修改: set path data: set /foo "Vox"
获取: get path: get /foo
删除: delete path: delete /foo
查看: ls path: ls /foo