Zookeeper基础
一、Zookeeper概述
什么是ZooKeeper
ZooKeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(Naming Service)、集群维护(Group Maintenance)等,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。ZooKeeper本身可以以Standalone模式安装运行,不过它的长处在于通过分布式ZooKeeper集群(一个Leader,多个Follower),基于一定的策略来保证ZooKeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。Zookeeper是一个分布式协调服务,为用户的分布式应用程序提供协调服务
1、zookeeper是为别的分布式程序服务的
2、Zookeeper本身就是一个分布式程序(只要有半数以上节点存活,zk就能正常服务)
3、Zookeeper所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统> 一名称服务等
4、虽然说可以提供各种服务,但是zookeeper在底层其实只提供了两个功能:
管理(存储,读取)用户程序提交的数据(类似namenode中存放的metadata);
并为用户程序提供数据节点监听服务;
二、Zookeeper结构
三、Windows环境下搭建Zookeeper
解压zookeeper-3.4.10.tar.gz ,重命名配置文件zoo_sample.cfg 为 zoo.cfg解压ZooInspector.zip(zk可视化客户端)
启动zk服务端:zkServer.cmd
启动zk客户端:zkCli.cmd
查看节点信息:ls /
创建节点信息:create /test 值
创建子节点信息:create /test/001 值
获取节点内容: get /test
修改节点内容: set /test "修该值"
删除节点 : delete /test
退出客户端:quit
四、Java语言操作Zookeeper
五、创建Zookeeper临时节点
六、Watcher事件通知
Zookeeper实战分布式锁
一、使用Zookeeper实现分布式锁概述
二、解决生产订单号线程安全问题
三、实现分布式锁解决方案
四、Zookeeper概述
五、使用Zookeeper实现分布式锁
/** * lock锁 自定义分布式锁 * Created by yz on 2018/4/7. */ public interface Lock { // 获取锁 public void getLock(); // 释放锁 public void unLock(); }
import org.I0Itec.zkclient.ZkClient; import java.util.concurrent.CountDownLatch; /** * 重构重复代码,将重复代码交给子类执行 * Created by yz on 2018/4/7. */ public abstract class ZookeeperAbstractLock implements Lock{ // zk连接地址 private static final String CONNECTSTRING="127.0.0.1:2181"; // 创建zk连接 protected ZkClient zkClient = new ZkClient(CONNECTSTRING); protected static final String PATH="/lock"; protected CountDownLatch countDownLatch = null; @Override public void getLock() { if(tryLock()){ System.out.println("-----获取锁成功-----"); }else{ // 等待 waitLock(); // 信号量通知,重新获取锁 getLock(); } } // 等待 abstract void waitLock(); // 是否获取锁成功,成功返回true,失败返回false abstract Boolean tryLock(); @Override public void unLock() { if(zkClient !=null){ zkClient.close(); System.out.println("释放锁资源成功"); } } }
import org.I0Itec.zkclient.IZkDataListener; import java.util.concurrent.CountDownLatch; /** * Created by yz on 2018/4/7. */ public class ZookeeperDistrbuteLock extends ZookeeperAbstractLock{ @Override void waitLock() { // 使用zk事件监听,获取到节点被删除 IZkDataListener iZkDataListener = new IZkDataListener() { // 当节点发生改变执行 @Override public void handleDataChange(String s, Object o) throws Exception { } // 当节点被删除后执行 @Override public void handleDataDeleted(String s) throws Exception { if(countDownLatch !=null){ // 唤醒await countDownLatch.countDown(); } } }; //注册节点信息 zkClient.subscribeDataChanges(PATH,iZkDataListener); // 检测节点 if(zkClient.exists(PATH)){ // 创建信号量 countDownLatch = new CountDownLatch(1); try { // 等待 countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } // 删除事件通知 zkClient.unsubscribeDataChanges(PATH,iZkDataListener); } /** * 是否获取锁成功,成功返回true,失败返回false */ @Override Boolean tryLock() { try { zkClient.createEphemeral(PATH); return true; } catch (RuntimeException e) { return false; } } }
import java.text.SimpleDateFormat; import java.util.Date; /** * 生成订单号规则 使用时间戳+业务id * Created by yz on 2018/4/7. */ public class OrderNumGenerator { // 业务ID private static int count = 0; //生成订单号 public String getNumber(){ try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); return simpleDateFormat.format(new Date())+"_"+ ++count; } }
/** * 订单生成调用业务逻辑 * Created by yz on 2018/4/7. */ public class OrderService implements Runnable{ // 生成订单号 OrderNumGenerator orderNumGenerator = new OrderNumGenerator(); // 使用zk分布式锁 private Lock lock = new ZookeeperDistrbuteLock(); @Override public void run() { try { //上锁 lock.getLock(); getNumber(); } catch (Exception e) { e.printStackTrace(); }finally { // 是否锁资源 lock.unLock(); } } public void getNumber(){ String number = orderNumGenerator.getNumber(); System.out.println(Thread.currentThread().getName()+",##number:"+number); } public static void main(String[] args) { System.out.println("#模拟生成订单号..."); for (int i = 0; i < 100; i++) { new Thread(new OrderService()).start(); } } }