zookeeperAPI
package zkApI;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
/**
* @Author: Braylon
* @Date: 2020/1/30 10:47
* @Version: 1.0
*/
public class zookeeper {
//对集群的配置,这里使用伪分布
private static String destination = "ip:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zkClient = null;
@Before
public void init() throws IOException {
zkClient = new ZooKeeper(destination, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
//收到事件通知后执行的函数,也就似乎用户的业务逻辑
System.out.println("监听" + "\001" + watchedEvent.getPath());
//重新开始监听
try {
zkClient.getChildren("/", true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
@Test
public void crearePoint() {
/*对于create方法
* P1:创建的节点路径
* P2:数据
* P3:节点的权限
* P4:节点的类型
* */
try {
zkClient.create("/braylon", "point01".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test
public void getChild() {
try {
List<String> children = zkClient.getChildren("/", true);
for (String c : children) {
System.out.println(c);
}
//延时阻塞
Thread.sleep(Long.MAX_VALUE);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test
public void isExited() {
try {
Stat s = zkClient.exists("/braylon", false);
System.out.println(s == null ? "不存在" : "存在");
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这里其实没有什么特别好说的,因为基本上都是很简单的操作,不过可以可以关注一下,@Before这个并不是zookeeper开发包中的,而是junit中的,答题的逻辑就是在运行Test之前先运行@Before注解下的监听器。
大家运行一些就明白了。
分布式锁
分布式锁一共有三种无非是利用原子性操作来达到。
- 数据库
- redis
- zookeeper锁
都可以实现分布式锁,
我知道的是redis用的好像比较多,当然我在上本科,所以也许是没有接触过特别高逼格的分布式锁。但是我一直觉得zookeeper锁使用比redis更加简单,主要应该是本身zookeeper的机制和开发包的封装性已经非常“傻瓜了”。
这里我分享一个小demo:
我使用的就是一个本地部署zookeeper的虚拟机,哈哈很简单吧。
package zkApI;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessLock;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* @Author: Braylon
* @Date: 2020/1/30 11:23
* @Version: 1.0
*/
public class zkDistributionLock {
private static Integer sharedResource = 5;
public static void print() {
System.out.println("**************" + Thread.currentThread().getName() + "**************");
System.out.println("Get sharedResource");
if (sharedResource == 0) {
System.out.println("sorry, your operation fails");
return;
}
sharedResource = sharedResource - 1;
System.out.println("left " + sharedResource);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("************************done\n");
}
public static void main(String[] args) {
//等待时间和最大重试次数
ExponentialBackoffRetry policy = new ExponentialBackoffRetry(1000, 10);
CuratorFramework client = CuratorFrameworkFactory.builder().connectString("ip:2181").retryPolicy(policy).build();
//生成锁
client.start();
final InterProcessMutex mutex = new InterProcessMutex(client, "/lock0130");
//多线程并发访问
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
//在访问共享资源之前获得锁
mutex.acquire();
print();
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放锁
try {
mutex.release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
}
}
欢迎大神指点
祝福武汉
大家共勉~~