zoukankan      html  css  js  c++  java
  • zookeeper 安装 测试及集群

    centos 安装 zookeeper-3.5.2-alpha.tar.gz

    网上搜索了 一下 安装教程 其实很简单

    主要总结一下 中间遇到的坑

    1.zookeeper 3.4.6 启动失败。

    很有可能是配置的日志目录在文件系统中没有新建。

    2.zookeeper 3.5+ 启动失败。

    这个是我今天遇上的问题,报错:

    [java] view plain copy

    print?
    2015-03-24 16:16:44,231 [myid:] - ERROR [main:ZooKeeperServerMain@72] - Unable to start AdminServer, exiting abnormally
    org.apache.zookeeper.server.admin.AdminServer$AdminServerException: Problem starting AdminServer on port 8080, command URL /commands
    at org.apache.zookeeper.server.admin.JettyAdminServer.start(JettyAdminServer.java:89)
    at org.apache.zookeeper.server.ZooKeeperServerMain.runFromConfig(ZooKeeperServerMain.java:123)
    at org.apache.zookeeper.server.ZooKeeperServerMain.initializeAndRun(ZooKeeperServerMain.java:99)
    at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerMain.java:57)
    at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:125)
    at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:79)
    Caused by: java.net.BindException: Address already in use
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
    at java.net.ServerSocket.bind(ServerSocket.java:376)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at java.net.ServerSocket.<init>(ServerSocket.java:181)
    at org.mortbay.jetty.bio.SocketConnector.newServerSocket(SocketConnector.java:80)
    at org.mortbay.jetty.bio.SocketConnector.open(SocketConnector.java:73)
    at org.mortbay.jetty.AbstractConnector.doStart(AbstractConnector.java:283)
    at org.mortbay.jetty.bio.SocketConnector.doStart(SocketConnector.java:147)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.Server.doStart(Server.java:235)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.apache.zookeeper.server.admin.JettyAdminServer.start(JettyAdminServer.java:85)
    ... 5 more

    很明显是由于端口占用。我服务器中的tomcat占用了8080端口,而zookeeper最近的版本中有个内嵌的管理控制台是通过jetty启动,也会占用8080 端口。

    通过查看zookeeper的官方文档,发现有3种解决途径:

    (1).删除jetty。

    (2)修改端口。

    修改方法的方法有两种,一种是在启动脚本中增加 -Dzookeeper.admin.serverPort=你的端口号.一种是在zoo.cfg中增加admin.serverPort=没有被占用的端口号

    (3)停用这个服务,在启动脚本中增加"-Dzookeeper.admin.enableServer=false"

    3.客户端使用的zookeeper和部署在服务端的版本不一致。(这个是网上有人说的,我也没遇到。)

    4.也有可能是 服务器防火墙 没有开启 zookeeper默认的2181 端口

    5.安装目录下 conf 里 默认的配置 文件 要改成 zoo.cfg 或者 复制 一份 改成 zoo.cfg

    附 zoo.cfg 配置

    tickTime=2000

    initLimit=5
    syncLimit=2
    dataDir=/opt/zookeeper/zookeeper/data
    clientPort=2181
    admin.serverPort=2182

    启动ZooKeeper服务器: bin/zkServer.sh start

    启动 CLI:bin/zkCli.sh

    停止ZooKeeper服务器:bin/zkServer.sh stop

    接下来 配置 zookeeper 集群

    网上看了 一些资料 都是  在同一台机器上 安装多个zookeeper 进行模拟的

    由于之前安装 nginx 的测试  多配置了 两台 虚拟机 所以 试着在多台机器上配置  集群

    配置文件如下:

    tickTime=2000

    initLimit=5
    syncLimit=2
    dataDir=/opt/zookeeper/zookeeper/data
    clientPort=2181
    admin.serverPort=2182
    server.1=192.168.3.125:2888:3888
    server.2=192.168.3.129:2888:3888
    server.3=192.168.3.130:2888:3888

     然后 添加  myid 文件

    在 /opt/zookeeper/zookeeper/data 这个文件里新建 myid 文件 里面的内容:

    在 192.168.3.125 上 myid 里内容为1

    192.168.3.129 上 myid 里内容为2

    192.168.3.130 上myid 里内容为 3

     130上客户端测试连接命令

    bin/zkCli.sh -server 192.168.3.125:2181

    下面说下 出现的问题:

    1、从 125 的日志里看到 以下报错信息

    刚开始 只看到 第一 和第四个 红线处的信息

    后来看到 第三处  才发现应该是端口没有打开   直接关闭了防火墙   问题就没再出现

    2、启动的时候 提示 java_home 找不到 没配置

    这个应该是 没有jdk 的缘故

    从网上搜了一下 安装了jdk

    在安装jdk 时 需要在 profile 配置  java_home path  classpath 配置好了以后 就要 执行 source /etc/profile  这个命令的意思是  使 profile 立即生效

    但是 发现一个问题

    安装jdk成功后 再启动 zookeeper 有时 还是会 报java_home 的报错
     这时 重新执行  source /etc/profile  这个命令   就可以了   不明所以

    接下来 测试下 用 java 进行连接  测试

    创建一个Maven工程

    打开pom.xml文件添加zookeeper依赖
     
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.6</version>
            </dependency>
    package feiye.zookeeper;
    
    import java.io.IOException;
    import java.util.concurrent.TimeUnit;
    
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.ZooDefs.Ids;
    import org.apache.zookeeper.ZooKeeper.States;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.WatchedEvent;
    
    public class Test {
        private static final int SESSION_TIMEOUT=30*1000;
        private ZooKeeper zk;
        private Watcher  wh=new Watcher ()
        {
            public void process(WatchedEvent  event)
            {
                System.out.println("WatchedEvent >> "+event);
            }
        };
        private void createZKInstance() throws IOException
        {
            zk=new ZooKeeper("192.168.3.125:2181,192.168.3.129:2181,192.168.3.130:2181",Test.SESSION_TIMEOUT,this.wh);
            if(!zk.getState().equals(States.CONNECTED))
            {
                while(true)
                {
                    if(zk.getState().equals(States.CONNECTED))
                    {
                        break;
                    }
                    try
                    {TimeUnit.SECONDS.sleep(5);}
                    catch(InterruptedException  e) {e.printStackTrace();}
                }
            }
        }
        private void ZKOperations() throws KeeperException, InterruptedException
        {
            System.out.println("
    1. 创建 ZooKeeper 节点 (znode : zoo2, 数据: myData2 ,权限: OPEN_ACL_UNSAFE ,节点类型: Persistent");
            //zk.create(path, data, acl, createMode)
            zk.create("/zoo2", "myData2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("
    2. 查看是否创建成功: ");
            System.out.println(new String(zk.getData("/zoo2", this.wh, null)));
            System.out.println("
    3. 修改节点数据");
            zk.setData("/zoo2", "shanhy20160310".getBytes(), -1);
            System.out.println("
    3-1. 再次修改节点数据");
            zk.setData("/zoo2", "shanhy20160310-ABCD".getBytes(), -1);
            System.out.println("
    4 查看节点是否修改成功");
            System.out.println(new String(zk.getData("/zoo2", false, null)));
            System.out.println("
    5 删除节点");
            zk.delete("/zoo2", -1);
            System.out.println("
    6. 查看节点是否被删除");
            System.out.println("节点状态:["+zk.exists("/zoo2", false)+"]");        
        }
        private void ZKClose() throws InterruptedException
        {
            zk.close();
        }
        public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
            Test dm=new Test();
            dm.createZKInstance();
            dm.ZKOperations();
            dm.ZKClose();
        }
    }

    上面的代码是基于zk提供的库的API来你使用的,为了更易于使用,有人写了开源的zkclient,我们可以直接使用它来操作zk。

    zkclient 开源地址:https://github.com/sgroschupf/zkclient
    maven 依赖配置:
     
            <!--zkclient -->
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.7</version>
            </dependency>

     zkClient 针对 zk 的一次性watcher,做了重新封装,然后定义了 stateChanged、znodeChanged、dataChanged 三种监听器。

     
    监听children变化
    监听节点数据变化
    监听连接状态变化
     这篇博客里 讲的不错 借鉴下
    http://www.cnblogs.com/shengkejava/p/5633801.html

    ZkClient使用

    1、jar包引入,演示版本为0.8,非maven项目,可以下载jar包导入到项目中

    <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.8</version>
    </dependency>

    2、创建Zookeeper连接

     示例:ZkClient zc = new ZkClient("192.168.117.128:2181",10000,10000,new SerializableSerializer());

     API:ZkClient(java.lang.String zkServers, int sessionTimeout, int connectionTimeout, org.I0Itec.zkclient.serialize.ZkSerializer zkSerializer)

    • zkServers:Zookeeper服务器地址
    • sessionTimeout:session超时时间
    • connectionTimeout:连接超时时间
    • zkSerializer:序列化器,ZkClient提供2种
      • SerializableSerializer:对象序列化,可转换对象
      • BytesPushThroughSerializer:字节数组序列化

    3、创建节点

       示例:

    复制代码
     @Test
        public void createNode() {
            createSession();
            User user = new User();
            user.setId(1l);
            user.setName("scot");
            String path = zc.create("/zkClient_01/02",user, CreateMode.PERSISTENT);
            System.out.println("path :" + path);
        }
    复制代码

     API:

    public java.lang.String create(java.lang.String path, java.lang.Object data, org.apache.zookeeper.CreateMode mode) public java.lang.String create(java.lang.String path, java.lang.Object data, java.util.List<org.apache.zookeeper.data.ACL> acl, org.apache.zookeeper.CreateMode mode) 

    示例用的为第一种,没有设置访问权限列表(List<org.apache.zookeeper.data.ACL> acl)

    • path:创建节点路径。(需要确保父路径存在)
    • data:节点数据。设置与获取要注意创建连接时候的序列化器
    • Acl:权限列表。详情查看 2.1Zookeeper原始API使用
    • mode:节点类型。详情查看 2.1Zookeeper原始API使用

    4、节点是否存在

      boolean exists(java.lang.String path);

    5、获取节点信息

     示例:

    复制代码
     @Test
        public void getNode() {
            createSession();
            User user = zc.readData("/zkClient_01");
            System.out.println(user.getName());
    
            Stat stat = new Stat();
            User user1 = zc.readData("/zkClient_01",stat);
            System.out.println(user.getName());
            System.out.println(stat);
        }
    复制代码

    API:

       public <T> T readData(java.lang.String path)public <T> T readData(java.lang.String path, boolean returnNullIfPathNotExists)public <T> T readData(java.lang.String path, org.apache.zookeeper.data.Stat stat)
    • path:节点路径。
    • returnnullIfPathNotExists:同字面意思,节点不存在返回null
    • stat:节点详细信息。传递stat对象到readData方法,方法内部会填充stat数据

    6、获取子节点

      示例:

    复制代码
    @Test
        public void getChild() {
            createSession();
            String path = "/node_scot";
            boolean b = this.exists(path);
            if(b) {
                List<String> children =zc.getChildren(path);
                System.out.println(children.size());
            }else {
                System.out.println("do not have this node");
            }
        }
    复制代码

     API:

       public java.util.List<java.lang.String> getChildren(java.lang.String path) 

    7、删除节点

      示例:   

    复制代码
     @Test
        public void del() {
            createSession();
            String path = "/zkClient_01/01";
            if(this.exists(path)) {
                //zc.delete(path);//删除当前节点,有子节点无法删除
                zc.deleteRecursive(path);//删除非子节点
            }
        }
    复制代码

     API:

    public boolean delete(java.lang.String path)
    
    public boolean delete(java.lang.String path, int version) 
    
    public boolean deleteRecursive(java.lang.String path) 
    • version:节点的版本。如果版本不符无法删除

     8、更新节点信息

      示例:

    复制代码
    @Test
        public void writeNode() {
            createSession();
            User user = new User();
            user.setId(11l);
            user.setName("sksujer002");
            zc.writeData("/zkClient_01",user);
        }
    复制代码

    9、监控子节点改变(当前节点不存在也可以设置监控)

     示例: 

    复制代码
        @Test
        public void subscribeChildChange() throws InterruptedException {
            createSession();
            zc.subscribeChildChanges("/zkClient_01",new MyZkChildListener());
            Thread.sleep(Integer.MAX_VALUE);
        }
    
        static class MyZkChildListener implements IZkChildListener {
    
            @Override
            public void handleChildChange(String s, List<String> strings) throws Exception {
                System.out.println("s:"+s);
                System.out.println("Strings:" + strings);
            }
        }
    复制代码

    API:

    public java.util.List<java.lang.String> subscribeChildChanges(java.lang.String path, org.I0Itec.zkclient.IZkChildListener listener)
    
    public interface IZkChildListener {
      void handleChildChange(java.lang.String parentPath, java.util.List<java.lang.String> currentChilds) throws java.lang.Exception;
    }
    • subscribeChildChanges:注册子节点改变监控
      • path:路径
      • IZkChildListener listener:子节点监控接口
    • IZkChildListener - handChildChange:子节点列表发生改变触发此方法
      • parentPath:监控节点路径
      • currentChilds:子节点列表

    10、监控节点数据

     示例:

    复制代码
     @Test
        public void subscribeDataChange () throws InterruptedException {
            createSession();
            zc.subscribeDataChanges("/zkClient_01",new MyZkDataListener());
            Thread.sleep(Integer.MAX_VALUE);
        }
    
        static class MyZkDataListener implements IZkDataListener {
    
            @Override
            public void handleDataChange(String s, Object o) throws Exception {
                System.out.println("节点信息改变");
                System.out.println("s:"+s);
                System.out.println("o:"+o);
            }
    
            @Override
            public void handleDataDeleted(String s) throws Exception {
                System.out.println("节点被删除:"+s);
            }
        }
    复制代码

    API:

    复制代码
     public void subscribeDataChanges(java.lang.String path, org.I0Itec.zkclient.IZkDataListener listener)
    
    
    public interface IZkDataListener {
    void handleDataChange(java.lang.String dataPath, java.lang.Object object) throws java.lang.Exception;
    
    void handleDataDeleted(java.lang.String dataPath) throws java.lang.Exception;
    }
    复制代码
    • subscribeDataChanges:注册节点数据监控
      • IZkDataListener listener:数据改变监控接口
    • IZkDataListener - handleDataChange:节点数据改变触发此方法
      • dataPath:监控节点路径
      • object:节点的新数据
    • IZkDataListener - handleDataDeleted:节点被删除触发此方法
      • dataPath:监控节点路径
     
  • 相关阅读:
    unity3d优化-代码篇(不定期更新)
    Activity的生命周期
    继承了AppCompatActivity的全屏设置
    shaderlab UV动画所需的变量声明
    加载Assetbundle需要注意的地方
    VisualStudio中的编辑后期生成事件
    unity3D射线检测敌人是否在前方
    Unity3D 定时发射子弹
    Unity3D使用NGUI做个弹窗
    Unity3D TouchScript 插件教程一
  • 原文地址:https://www.cnblogs.com/feiye512/p/5923683.html
Copyright © 2011-2022 走看看