Zookeeper实战之嵌入式运行Zookeeper集群模式

2019-04-14 21:56发布

很多使用Zookeeper的情景是需要我们嵌入Zookeeper作为自己的分布式应用系统的一部分来提供分布式服务,此时我们需要通过程序的方式来启动Zookeeper。此时可以通过Zookeeper API的ZooKeeperServerMain类来启动Zookeeper服务。
 
下面是一个集群模式下启动Zookeeper服务的例子
 
这里假定我们运行Zookeeper集群的三台机器名分别为fanbinx1,fanbinx2,fanbinx3
 
首先是zoo.cfg配置文件tickTime=2000 dataDir=/tmp/zookeeper/data clientPort=2181 initLimit=10 syncLimit=5 server.1=fanbinx1:2888:3888 server.2=fanbinx2:2888:3888 server.3=fanbinx3:2888:3888启动Zookeeper集群服务的类,如下 
* 这个类同时使用同一个zoo.cfg配置文件来启动Zookeeper服务。
* 在每台机器上启动Zookeeper服务的时候判断当前机器是不是定义在zoo.cfg文件里,如果是获取其中的ID号,然后生成myid文件并将ID写入其中。
* 最后启动Zookeeper服务。package my.zookeeperstudy.server; import org.apache.commons.io.FileUtils; import org.apache.zookeeper.server.ServerConfig; import org.apache.zookeeper.server.ZooKeeperServerMain; import org.apache.zookeeper.server.quorum.QuorumPeerConfig; import java.io.File; import java.io.InputStream; import java.net.InetAddress; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ClusteredZKServer { public static void main(String[] args) throws Exception { InputStream is = ClusteredZKServer.class.getResourceAsStream("/my/zookeeperstudy/server/zoo.cfg"); Properties props = new Properties(); try { props.load(is); } finally { is.close(); } for (String key : props.stringPropertyNames()) { Pattern pKey = Pattern.compile("^server\.(\d)"); Pattern pValue = Pattern.compile("([\w|.]*):\d*:\d*"); Matcher mKey = pKey.matcher(key); Matcher mValue = pValue.matcher(props.getProperty(key)); if (mKey.find() && mValue.find()) { String id = mKey.group(1); String host = mValue.group(1); String thisHostName = InetAddress.getLocalHost().getHostName(); String thisHostAddress = InetAddress.getLocalHost().getHostAddress(); if (host.equals(thisHostName) || host.equals(thisHostAddress)) { //System.out.println(new File(props.getProperty("dataDir"), "myid").getAbsolutePath()); FileUtils.write(new File(props.getProperty("dataDir"), "myid"), id); QuorumPeerConfig quorumConfig = new QuorumPeerConfig(); quorumConfig.parseProperties(props); final ZooKeeperServerMain zkServer = new ZooKeeperServerMain(); final ServerConfig config = new ServerConfig(); config.readFrom(quorumConfig); zkServer.runFromConfig(config); } } } } }客户端测试代码如下,这里可以修改hostname为集群中的任意一台机器
package my.zookeeperstudy.server; import org.apache.zookeeper.*; import java.util.List; public class Client { public static void main(String[] args) throws Exception { ZooKeeper zk = new ZooKeeper("fanbinx1:2181,fanbinx2:2181,fanbinx3:2181", 10000, new Watcher() { public void process(WatchedEvent event) { System.out.println("event: " + event.getType()); } }); System.out.println(zk.getState()); zk.create("/myApps", "myAppsData".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.create("/myApps/App1", "App1Data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.create("/myApps/App2", "App2Data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.create("/myApps/App3", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk.setData("/myApps/App3","App3Data".getBytes(), -1); System.out.println(zk.exists("/myApps", true)); System.out.println(new String(zk.getData("/myApps", true, null))); List children = zk.getChildren("/myApps", true); for (String child : children) { System.out.println(new String(zk.getData("/myApps/" + child, true, null))); zk.delete("/myApps/" + child,-1); } zk.delete("/myApps",-1); zk.close(); } }
测试
* 在集群中的各个机器上分别运行ClusteredZKServer类来启动Zookeeper服务。
* 然后在任意一台机器上运行Client类来连接Zookeeper并操作数据。
原文链接:Zookeeper实战之嵌入式运行Zookeeper集群模式