zookeeper分布式原理实战解析
来源:互联网 发布:远程数据采集器 编辑:程序博客网 时间:2024/06/05 06:56
1.本实验基于centos7.3 +虚拟机VM+zookeeper-3.4.5.tar.gz环境下安装了三台集群测试。
安装参考:http://www.linuxidc.com/Linux/2016-09/135052.htm
启动zookeeper集群shell脚本
#!/bin/bashcd /opt/apps/zookeeper/bin ./zkServer.sh start ssh -tt root@192.168.32.131 > /dev/null 2>&1 << remotesshcd /opt/apps/zookeeper/bin./zkServer.sh startexit remotessh ssh -tt root@192.168.32.130 > /dev/null 2>&1 << remotesshcd /opt/apps/zookeeper/bin ./zkServer.sh start exit remotessh
停止脚本:
#!/bin/bash cd /opt/apps/zookeeper/bin ./zkServer.sh stop ssh -tt root@192.168.32.130 > /dev/null 2>&1 << remotessh cd /opt/apps/zookeeper/bin ./zkServer.sh stop exit remotessh ssh -tt root@192.168.32.131 > /dev/null 2>&1 << remotessh cd /opt/apps/zookeeper/bin ./zkServer.sh stop exit remotessh
2.zookeeper的服务上下线监听:
结构流程图:
实验测试:
服务端代码:
package com.ljt.zk.zkdist;import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.CreateMode;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.ZooDefs.Ids;import org.apache.zookeeper.ZooKeeper;import org.apache.zookeeper.ZooKeeper.States;/** * * <p>Title: DistributedServer</p> * <p> 功能描述:: </p> * <p>Company: adteach </p> * @author 刘建涛 * * @date 2017年7月7日上午11:09:25 * @version 1.0 */public class DistributedServer { // private static final String connectString = // "192.168.32.129:2181,192.168.32.130:2182,192.168.32.131:2183"; private static final String connectString = "192.168.32.129:2181"; private static final int sessionTimeout = 15000; private static final String parentNode = "/servers"; private ZooKeeper zk = null; /** * 创建到zk的客户端连接 * * @throws Exception */ public void getConnect(String agr) throws Exception { //连接不成功等待连接 while (true) { zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { try { zk.getChildren("/servers", true); // 收到事件通知后的回调函数(应该是我们自己的事件处理逻辑) System.out.println(event.getType() + "---" + event.getPath()); // 利用zk连接注册服务器信息 registerServer(agr); // 启动业务功能 handleBussiness(agr); } catch (Exception e) { } } }); if(States.CONNECTED != zk.getState()){ CountDownLatch connectedLatch = new CountDownLatch(1); System.err.println("等待连接……"); connectedLatch.await(); }else{ System.err.println("连接成功!!!"); break; } } } /** * 向zk集群注册服务器信息 * * @param hostname * @throws Exception */ public void registerServer(String hostname) throws Exception { String create = zk.create(parentNode + "/server", hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); System.out.println(hostname + "is online.." + create); } /** * 业务功能 * * @throws InterruptedException */ public void handleBussiness(String hostname) throws InterruptedException { System.out.println(hostname + "start working....."); Thread.sleep(Long.MAX_VALUE); } public static void main(String[] args) throws Exception { // 获取zk连接 DistributedServer server = new DistributedServer(); server.getConnect(args[0]); }}
启动时向main函数中注入参数结果如下:
打成jar包运行命令:java -jar jar包 参数
log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKeeper).
log4j:WARN Please initialize the log4j system properly.
等待连接……
None—null
www.ljt.cos01is online../servers/server0000000002
www.ljt.cos01start working…..
客服端代码:
package com.ljt.zk.zkdist;import java.util.ArrayList;import java.util.List;import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.KeeperException;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.ZooKeeper;import org.apache.zookeeper.ZooKeeper.States;/*** * * <p>Title: DistributedClient</p> * <p> 功能描述:: </p> * <p>Company: adteach </p> * @author 刘建涛 * * @date 2017年7月7日上午11:12:48 * @version 1.0 */public class DistributedClient { private static final String connectString = "192.168.32.129:2181,192.168.32.130:2182,192.168.32.131:2183"; private static final int sessionTimeout = 8000; private static final String parentNode = "/servers"; // 注意:加volatile的意义何在? private volatile List<String> serverList; private ZooKeeper zk = null; /** * 创建到zk的客户端连接 * * @throws Exception */ public void getConnect() throws Exception { zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { // 收到事件通知后的回调函数(应该是我们自己的事件处理逻辑) try { // 重新更新服务器列表,并且注册了监听 getServerList(); } catch (Exception e) { } } }); CountDownLatch connectedLatch = new CountDownLatch(1); if (States.CONNECTING == zk.getState()) { try { connectedLatch.await(); } catch (InterruptedException e) { throw new IllegalStateException(e); } } } /** * 获取服务器信息列表 * * @throws Exception */ public void getServerList() throws Exception { // 获取服务器子节点信息,并且对父节点进行监听 List<String> children = zk.getChildren(parentNode, true); // 先创建一个局部的list来存服务器信息 List<String> servers = new ArrayList<String>(); for (String child : children) { // child只是子节点的节点名 byte[] data = zk.getData(parentNode + "/" + child, false, null); servers.add(new String(data)); } // 把servers赋值给成员变量serverList,已提供给各业务线程使用 serverList = servers; // 打印服务器列表 System.out.println(serverList); } /** * 业务功能 * * @throws InterruptedException */ public void handleBussiness() throws InterruptedException { System.out.println("client start working....."); Thread.sleep(Long.MAX_VALUE); } public static void main(String[] args) throws Exception { // 获取zk连接 DistributedClient client = new DistributedClient(); client.getConnect(); // 获取servers的子节点信息(并监听),从中获取服务器信息列表 client.getServerList(); // 业务线程启动 client.handleBussiness(); }}
3.分布式共享锁
分布式锁结构流程图:
完整代码:
package com.ljt.zk.zklock;import java.util.Collections;import java.util.List;import java.util.Random;import org.apache.zookeeper.CreateMode;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.Watcher.Event.EventType;import org.apache.zookeeper.ZooDefs.Ids;import org.apache.zookeeper.ZooKeeper;public class DistributedClientLock { // 会话超时 private static final int SESSION_TIMEOUT = 2000; // zookeeper集群地址 private String hosts = "192.168.32.129:2181,192.168.32.130:2182,192.168.32.131:2183"; private String groupNode = "locks"; private String subNode = "sub"; private boolean haveLock = false; private ZooKeeper zk; // 记录自己创建的子节点路径 private volatile String thisPath; /** * 连接zookeeper */ public void connectZookeeper() throws Exception { zk = new ZooKeeper(hosts, SESSION_TIMEOUT, new Watcher() { public void process(WatchedEvent event) { try { // 判断事件类型,此处只处理子节点变化事件 if (event.getType() == EventType.NodeChildrenChanged && event.getPath().equals("/" + groupNode)) { //获取子节点,并对父节点进行监听 List<String> childrenNodes = zk.getChildren("/" + groupNode, true); String thisNode = thisPath.substring(("/" + groupNode + "/").length()); // 去比较是否自己是最小id 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(); } } }); // 1、程序一进来就先注册一把锁到zk上 thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); // wait一小会,便于观察 Thread.sleep(new Random().nextInt(1000)); // 从zk的锁父目录下,获取所有子节点,并且注册对父节点的监听 List<String> childrenNodes = zk.getChildren("/" + groupNode, true); //如果争抢资源的程序就只有自己,则可以直接去访问共享资源 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); // 删除节点 zk.delete(this.thisPath, -1); } } public static void main(String[] args) throws Exception { DistributedClientLock dl = new DistributedClientLock(); dl.connectZookeeper(); Thread.sleep(Long.MAX_VALUE); }}
阅读全文
0 0
- zookeeper分布式原理实战解析
- 分布式实战--zookeeper
- zookeeper 分布式锁原理:
- zookeeper 分布式锁解析
- Zookeeper原理与实战
- Zookeeper实战之分布式锁
- Dubbo+Zookeeper伪分布式实战
- 大规模分布式存储系统原理解析与架构实战
- 《大规模分布式存储系统:原理解析与架构实战》读书笔记(1)
- 《大规模分布式存储系统:原理解析与架构实战》读书笔记
- 大规模分布式存储系统:原理解析与架构实战
- 大规模分布式存储系统原理解析与架构实战
- ZooKeeper分布式锁实现原理
- zookeeper原理:分布式协同技术
- 分布式锁实现zookeeper原理
- zookeeper分布式锁实现原理
- zookeeper工作原理解析
- zookeeper原理解析
- Android实现透明状态栏方法以及改变状态栏文字颜色
- 关于使用Maven管理引入Oracle驱动报错
- 关于android 消息提醒,在网上找到这个项目在eslipse中使用ValueAnimator报错
- 文章标题
- heap和stack的不同
- zookeeper分布式原理实战解析
- Side-Menu源码分析讲解
- C#操作Word文档(加密、解密、对应书签插入分页符)
- 以太坊与节点的交互 JSON RPC API 和Web3.js
- Service总结(一)
- springMVC+spring4+hibernate4+bootstrap+layui以及自己封装的通用类
- 从0开始做后台测试
- ContextLoaderListener作用详解
- oracle创建数据表之前如果存在数据表就删除,之后创建新数据表