设为首页 收藏本站
查看: 1523|回复: 0

[经验分享] zookeeper 安装 测试及集群

[复制链接]

尚未签到

发表于 2017-3-2 10:06:09 | 显示全部楼层 |阅读模式
  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 的日志里看到 以下报错信息
DSC0000.png

  刚开始 只看到 第一 和第四个 红线处的信息
  后来看到 第三处  才发现应该是端口没有打开   直接关闭了防火墙   问题就没再出现
  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("\n1. 创建 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("\n2. 查看是否创建成功: ");
System.out.println(new String(zk.getData("/zoo2", this.wh, null)));
System.out.println("\n3. 修改节点数据");
zk.setData("/zoo2", "shanhy20160310".getBytes(), -1);
System.out.println("\n3-1. 再次修改节点数据");
zk.setData("/zoo2", "shanhy20160310-ABCD".getBytes(), -1);
System.out.println("\n4 查看节点是否修改成功");
System.out.println(new String(zk.getData("/zoo2", false, null)));
System.out.println("\n5 删除节点");
zk.delete("/zoo2", -1);
System.out.println("\n6. 查看节点是否被删除");
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、创建节点
  示例:




DSC0001.gif
@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:监控节点路径


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-349146-1-1.html 上篇帖子: Maven构建多模块项目 下篇帖子: dubbo 运行过程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表