步骤:

1- pom.xml

<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>

2- yml配置:

zk:
  url: 127.0.0.1:2181
  localPath: /newlock
  timeout: 3000

3- 配置类

package com.test.domi.config;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class ZookeeperConf { @Value("${zk.url}")
private String zkUrl; @Bean
public CuratorFramework getCuratorFramework(){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
CuratorFramework client = CuratorFrameworkFactory.newClient(zkUrl,retryPolicy);
client.start();
return client;
}
}

4- 使用

package com.test.domi.common.utils.lock;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock; @Component("zklock")
public class ZKlock implements Lock { @Autowired
private CuratorFramework zkClient;
@Value("${zk.localPath}")
private String lockPath;
private String currentPath;
private String beforePath; @Override
public boolean tryLock() {
try {
//根节点的初始化放在构造函数里面不生效
if (zkClient.checkExists().forPath(lockPath) == null) {
System.out.println("初始化根节点==========>" + lockPath);
zkClient.create().creatingParentsIfNeeded().forPath(lockPath);
}
System.out.println("当前线程" + Thread.currentThread().getName() + "初始化根节点" + lockPath);
} catch (Exception e) {
} if (currentPath == null) {
try {
currentPath = this.zkClient.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath(lockPath + "/");
} catch (Exception e) {
return false;
}
}
try {
//此处该如何获取所有的临时节点呢?如locks00004.而不是获取/locks/order中的order作为子节点??
List<String> childrens = this.zkClient.getChildren().forPath(lockPath);
Collections.sort(childrens);
if (currentPath.equals(lockPath + "/" + childrens.get(0))) {
System.out.println("当前线程获得锁" + currentPath);
return true;
}else{
//取前一个节点
int curIndex = childrens.indexOf(currentPath.substring(lockPath.length() + 1));
//如果是-1表示children里面没有该节点
beforePath = lockPath + "/" + childrens.get(curIndex - 1);
}
} catch (Exception e) {
return false;
}
return false;
} @Override
public void lock() {
if (!tryLock()) {
waiForLock();
lock();
}
} @Override
public void unlock() {
try {
zkClient.delete().guaranteed().deletingChildrenIfNeeded().forPath(currentPath);
} catch (Exception e) {
//guaranteed()保障机制,若未删除成功,只要会话有效会在后台一直尝试删除
}
} private void waiForLock(){
CountDownLatch cdl = new CountDownLatch(1);
//创建监听器watch
NodeCache nodeCache = new NodeCache(zkClient,beforePath);
try {
nodeCache.start(true);
nodeCache.getListenable().addListener(new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
cdl.countDown();
System.out.println(beforePath + "节点监听事件触发,重新获得节点内容为:" + new String(nodeCache.getCurrentData().getData()));
}
});
} catch (Exception e) {
}
//如果前一个节点还存在,则阻塞自己
try {
if (zkClient.checkExists().forPath(beforePath) == null) {
cdl.await();
}
} catch (Exception e) {
}finally {
//阻塞结束,说明自己是最小的节点,则取消watch,开始获取锁
try {
nodeCache.close();
} catch (IOException e) {
}
}
} @Override
public void lockInterruptibly() throws InterruptedException {
} @Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
} @Override
public Condition newCondition() {
return null;
} }

5- 调用demo

package com.test.domi.controller;

import com.test.domi.common.utils.ZkUtil;
import com.test.domi.common.utils.lock.ZKlock;
import org.I0Itec.zkclient.ZkClient;
import org.apache.curator.framework.CuratorFramework;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/zk")
public class ZKController { @Autowired
private CuratorFramework zkClient;
// @Autowired
// private ZkClient zkClient; private String url = "127.0.0.1:2181";
private int timeout = 3000;
private String lockPath = "/testl";
@Autowired
private ZKlock zklock;
private int k = 1; @GetMapping("/lock")
public Boolean getLock() throws Exception{ for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
zklock.lock();           zklock.unlock();
} }).start(); }
return true; } }

springboot2整合zookeeper集成curator的更多相关文章

  1. SpringBoot2 整合 Zookeeper组件,管理架构中服务协调

    本文源码:GitHub·点这里 || GitEE·点这里 一.Zookeeper基础简介 1.概念简介 Zookeeper是一个Apache开源的分布式的应用,为系统架构提供协调服务.从设计模式角度来 ...

  2. SpringBoot2整合activiti6环境搭建

    SpringBoot2整合activiti6环境搭建 依赖 <dependencies> <dependency> <groupId>org.springframe ...

  3. SpringBoot2 整合Kafka组件,应用案例和流程详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.搭建Kafka环境 1.下载解压 -- 下载 wget http://mirror.bit.edu.cn/apache/kafka/2.2 ...

  4. SpringBoot2 整合Ehcache组件,轻量级缓存管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.Ehcache缓存简介 1.基础简介 EhCache是一个纯Java的进程内缓存框架,具有快速.上手简单等特点,是Hibernate中默认 ...

  5. (十七)整合 Zookeeper组件,管理架构中服务协调

    整合 Zookeeper组件,管理架构中服务协调 1.Zookeeper基础简介 1.1 基本理论 1.2 应用场景 2.安全管理操作 2.1 操作权限 2.2 认证方式: 2.3 Digest授权流 ...

  6. Zookeeper客户端Curator使用详解

    Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBoot.Curator.Bootstrap写了一个可视化的Web应用: zookeep ...

  7. zookeeper(六):Zookeeper客户端Curator的API使用详解

    简介 Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连.反复注册Watcher和NodeExistsEx ...

  8. java springboot整合zookeeper入门教程(增删改查)

    java springboot整合zookeeper增删改查入门教程 zookeeper的安装与集群搭建参考:https://www.cnblogs.com/zwcry/p/10272506.html ...

  9. 转:Zookeeper客户端Curator使用详解

    原文:https://www.jianshu.com/p/70151fc0ef5d Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBo ...

随机推荐

  1. IDEA下载安装及绿色方法

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  2. Python 之 subprocess模块

    一.subprocess以及常用的封装函数运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python ...

  3. koa 基础(六)应用级路由中间件

    1.应用级路由中间件 app.js /** * 应用级路由中间件 */ // 引入模块 const Koa = require('koa'); const router = require('koa- ...

  4. Python3并发写文件

    使用python2在进行并发写的时候,发现文件会乱掉,就是某一行中间会插入其他行的内容. 但是在使用python3进行并发写的时候,无论是多进程,还是多线程,都没有出现这个问题,难道是python3的 ...

  5. ThinkPhp sql语句执行方法

    ThinkPHP内置的ORM和ActiveRecord模式实现了方便的数据存取操作,而且新版增加的连贯操作功能更是让这个数据操作更加清晰,但是ThinkPHP仍然保留了原生的SQL查询和执行操作支持, ...

  6. OGG 从Oracle备库同步数据至kafka

    OGG 从Oracle备库同步数据至kafka Table of Contents 1. 目的 2. 环境及规划 3. 安装配置JDK 3.1. 安装jdk 3.2. 配置环境变量 4. 安装Data ...

  7. TreeSet简单介绍与使用方法

    TreeSet简介 TreeSet是JAVA中集合的一种,TreeSet 是一个有序的集合,它的作用是提供有序的Set集合.它继承于AbstractSet抽象类,实现了NavigableSet< ...

  8. The inherit, initial, and unset values

    The  inherit, initial, and unset keywords are special values you can give to any CSS property. Tests ...

  9. golang(09) golang 接口内部实现

    原文链接 http://www.limerence2017.com/2019/09/24/golang14/#more 前文介绍过golang interface用法,本文详细剖析interface内 ...

  10. jdk1.8-LinkedList源码分析

    一:类的继承关系 我们看下类的继承关系 ) ) )) { ; i > index; i--) //当前记录结点等于上一节点 x = x.prev; //返回索引为index的点! return ...