一、集群自启动脚本

  1.关闭zk

  1. [root@localhost bin]# jps
  2. Jps
  3. QuorumPeerMain
  4. [root@localhost bin]# kill -

  //kill或者stop都是可以的

  2.远程执行命令

  1. [root@localhost bin]# ssh 192.168.137.138 /opt/zookeeper/zookeeper-3.4./bin/zkServer.sh start
  2. root@192.168.137.138's password:
  3. JMX enabled by default
  4. Using config: /opt/zookeeper/zookeeper-3.4./bin/../conf/zoo.cfg
  5. Starting zookeeper ... /opt/zookeeper/zookeeper-3.4./bin/zkServer.sh: 第 行:[: /tmp/zookeeper: 期待二元表达式
  6. STARTED

  出现以上中文的地方只需要修改一下zoo.cfg,把多余的配置注释即可!

  当然,这样还是无法启动!因为ssh过去是以一个bash的方式过去的(不会执行/etc/profile,而正常登录是会执行的,也可以打开相应的脚本进行查看),也就是PATH不在了,导致JAVA_HOME等找不到了!

  EXPORT所定义的变量对自己所在的shell以及子shell生效

  这里就需要用到之前说到的source命令了:https://www.cnblogs.com/pkufork/p/linux_source.html

  1. ssh 192.168.137.138 "source /etc/profile&&/opt/zookeeper/zookeeper-3.4.5/bin/zkServer.sh start"

  //如果不使用引号,将会以空格作为命令的分割!

  3.配置免密登录

  在其中一台机器上(这里是192.168.137.128)

  1. ssh-keygen

  //之后enter即可

  1. ssh-copy-id 192.168.137.128
  2. ssh-copy-id 192.168.137.138
  3. ssh-copy-id 192.168.137.148

  4.一键启动脚本

  1. cd /root
  2. mkdir bin
  3. cd bin
  4. vim startZK.sh
  1. #!/bin/bash
  2. SERVERS="192.168.137.128 192.168.137.138 192.168.137.148"
  3. echo "start zk..."
  4. for SERVER in $SERVERS
  5. do
  6. ssh $SERVER "source /etc/profile&&/opt/zookeeper/zookeeper-3.4.5/bin/zkServer.sh start"
  7. done
  1. chmod +x startZK.sh

  这样,通过startZK.sh就能一键启动了!(/root/bin默认在PATH中了!)

二、zk的Java客户端

  相关API入门可以参考:https://www.cnblogs.com/ggjucheng/p/3370359.html

  第三方的客户端:zkclient参考:https://www.cnblogs.com/f1194361820/p/5575206.html

  1.引入maven依赖

  1. <dependency>
  2. <groupId>org.apache.zookeeper</groupId>
  3. <artifactId>zookeeper</artifactId>
  4. <version>3.4.6</version>
  5. </dependency>

  2.测试程序是否能通

  1. public class SimpleZK {
  2. // 设置连接字符串(可以用逗号隔开多个),失败时会自动尝试多个
  3. private static final String coonectString = "192.168.137.128:2181,192.168.137.138:2181,192.168.137.148:2181";
  4. // 超时时间
  5. private static final int sessionTimeout = 2000;
  6. public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
  7. ZooKeeper zkClient = new ZooKeeper(coonectString, sessionTimeout, new Watcher() {
  8. public void process(WatchedEvent watchedEvent) {
  9. // 收到通知事件后的回调函数
  10. System.out.println(watchedEvent.getType()+"---"+watchedEvent.getPath());
  11. }
  12. });
  13. // zk的增删改查(这里使用最底层的原生操作,zkclient的待补充)
  14. String node = zkClient.create("/app2", "hellozk".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  15.  
  16. }
  17.  
  18. }

  完美:

    

  3.增删改查实例

  1. package com.zk;
  2.  
  3. import org.apache.zookeeper.*;
  4. import org.apache.zookeeper.data.Stat;
  5. import org.junit.Before;
  6. import org.junit.Test;
  7.  
  8. import java.io.IOException;
  9. import java.util.List;
  10.  
  11. /**
  12. * 测试zk的Java客户端
  13. *
  14. * @author zcc ON 2018/1/17
  15. **/
  16. public class SimpleZK {
  17. // 设置连接字符串(可以用逗号隔开多个),失败时会自动尝试多个
  18. private static final String coonectString = "192.168.137.128:2181,192.168.137.138:2181,192.168.137.148:2181";
  19. // 超时时间
  20. private static final int sessionTimeout = 2000;
  21. // 初始变量
  22. ZooKeeper zkClient = null;
  23.  
  24. /**
  25. * 初始化方法
  26. * @throws IOException
  27. */
  28. @Before
  29. public void init() throws IOException {
  30. zkClient = new ZooKeeper(coonectString, sessionTimeout, new Watcher() {
  31. public void process(WatchedEvent watchedEvent) {
  32. // 收到通知事件后的回调函数
  33. System.out.println(watchedEvent.getType()+"---"+watchedEvent.getPath());
  34. // 开启循环监听(监听调用此方法,此方法又开启监听)
  35. try {
  36. zkClient.getChildren("/", true);
  37. } catch (KeeperException e) {
  38. e.printStackTrace();
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. });
  44. }
  45.  
  46. /**
  47. * 创建
  48. */
  49. public void testCreate() throws IOException, KeeperException, InterruptedException {
  50. String node = zkClient.create("/app2", "hellozk".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  51. }
  52.  
  53. /**
  54. * 判断是否存在节点
  55. * @throws KeeperException
  56. * @throws InterruptedException
  57. */
  58. public void testExists() throws KeeperException, InterruptedException {
  59. // stat就是zk中那一堆数据(null则不存在)
  60. Stat stat = zkClient.exists("/", false);
  61. }
  62. /**
  63. * 取得子节点
  64. */
  65. @Test
  66. public void testGetChildren() throws KeeperException, InterruptedException {
  67. List<String> children = zkClient.getChildren("/", true);
  68. for (String child : children) {
  69. System.out.println(child);
  70. }
  71. }
  72.  
  73. /**
  74. * 获取数据
  75. */
  76. @Test
  77. public void testGetData() throws KeeperException, InterruptedException {
  78. // 分别是路径,是否监听以及状态版本(null就OK了,取最新)
  79. byte[] data = zkClient.getData("/app2", false, null);
  80. System.out.println(new String(data));
  81. }
  82.  
  83. /**
  84. * 删除数据
  85. */
  86. @Test
  87. public void testDeleteZnode() throws KeeperException, InterruptedException {
  88. // -1作为版本号参数表示删除所有版本(上层的API是不用传这些参数的)
  89. zkClient.delete("/app2",-1);
  90. }
  91.  
  92. /**
  93. * 修改数据
  94. */
  95. public void testSetData() throws KeeperException, InterruptedException {
  96. zkClient.setData("/app2", "hellozkCli".getBytes(), -1);
  97. }
  98. }

三、应用实例

  1.分布式服务器动态上下线感知(主节点HA)

  大致原理:

    

  大致流程比较清晰,当服务器启动时就去注册信息(例如给出主机与id等信息),给出一个短暂的带序列号的临时节点,这样服务器下线的时候节点便被删除了;而客户端则是去zk获取子节点信息,得到服务器列表并且注册监听,这样当有节点发生改变时变可以感知变化了!

  2.Java代码

    IDEA中给main方法添加参数,参考:http://blog.csdn.net/u013713294/article/details/53020293

  服务都端:

  1. package com.zk;
  2.  
  3. import org.apache.zookeeper.*;
  4.  
  5. import java.io.IOException;
  6.  
  7. /**
  8. * 分布式服务器动态感知——服务端
  9. *
  10. * @author zcc ON 2018/1/17
  11. **/
  12. public class DistributedServer {
  13.  
  14. private static final String coonectString = "192.168.137.128:2181,192.168.137.138:2181,192.168.137.148:2181";
  15. private static final int sessionTimeout = 2000;
  16. private static final String parentNode = "/servers";
  17.  
  18. private ZooKeeper zk = null;
  19.  
  20. /**
  21. * 获得连接
  22. * @throws IOException
  23. */
  24. public void getConn() throws IOException {
  25. zk = new ZooKeeper(coonectString, sessionTimeout, new Watcher() {
  26. public void process(WatchedEvent watchedEvent) {
  27. // 收到通知事件后的回调函数
  28. System.out.println(watchedEvent.getType()+"---"+watchedEvent.getPath());
  29. // 开启循环监听(监听调用此方法,此方法又开启监听)
  30. try {
  31. zk.getChildren("/", true);
  32. } catch (KeeperException e) {
  33. e.printStackTrace();
  34. } catch (InterruptedException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. });
  39. }
  40.  
  41. /**
  42. * 注册服务器
  43. */
  44. public void registServer(String hostname) throws KeeperException, InterruptedException {
  45. // 临时有编号的节点,可以重名
  46. String znode = zk.create(parentNode + "/server", hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
  47. System.out.println(hostname+" is online..."+znode);
  48. }
  49.  
  50. /**
  51. * 业务逻辑
  52. */
  53. public void handleBI(String hostname) throws InterruptedException {
  54. System.out.println(hostname+" start working...");
  55. // 模拟保持不关闭状态
  56. Thread.sleep(Long.MAX_VALUE);
  57. }
  58.  
  59. public static void main(String[] args) throws Exception {
  60. // 获取zk连接
  61. DistributedServer servers = new DistributedServer();
  62. servers.getConn();
  63. // 注册服务器
  64. servers.registServer(args[0]);
  65. // 业务逻辑
  66. servers.handleBI(args[0]);
  67. }
  68. }

  客户端:

  1. package com.zk;
  2.  
  3. import org.apache.zookeeper.KeeperException;
  4. import org.apache.zookeeper.WatchedEvent;
  5. import org.apache.zookeeper.Watcher;
  6. import org.apache.zookeeper.ZooKeeper;
  7.  
  8. import java.io.IOException;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11.  
  12. /**
  13. * 分布式服务器动态感知——客户端
  14. *
  15. * @author zcc ON 2018/1/17
  16. **/
  17. public class DistributedClient {
  18. private static final String coonectString = "192.168.137.128:2181,192.168.137.138:2181,192.168.137.148:2181";
  19. private static final int sessionTimeout = 2000;
  20. private static final String parentNode = "/servers";
  21. // 注意volatile的使用意义(使每个线程都得到最新值)
  22. private volatile List<String> serverList;
  23.  
  24. private ZooKeeper zk = null;
  25.  
  26. /**
  27. * 获得连接
  28. * @throws IOException
  29. */
  30. public void getConn() throws IOException {
  31. zk = new ZooKeeper(coonectString, sessionTimeout, new Watcher() {
  32. public void process(WatchedEvent watchedEvent) {
  33. try {
  34. // 回调事件重新更新服务器列表并注册监听
  35. getServerList();
  36. } catch (KeeperException e) {
  37. e.printStackTrace();
  38. } catch (InterruptedException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. });
  43. }
  44.  
  45. /**
  46. * 业务逻辑
  47. */
  48. public void handleBI() throws InterruptedException {
  49. System.out.println("client working...");
  50. // 模拟保持不关闭状态
  51. Thread.sleep(Long.MAX_VALUE);
  52. }
  53. public void getServerList() throws KeeperException, InterruptedException {
  54. // 获取服务器子节点信息,并且对父节点监听
  55. List<String> children = zk.getChildren(parentNode, true);
  56. // 用于存放服务器列表的List
  57. List<String> servers = new ArrayList<>();
  58. for (String child : children) {
  59. // 获取数据(这里无需监听,因为连接上了不需要更换连接了)
  60. byte[] data = zk.getData(parentNode + "/" + child, false, null);
  61. servers.add(new String(data));
  62. }
  63. // 更新到成员变量,供业务线程使用
  64. serverList = servers;
  65. // 打印服务器列表
  66. System.out.println(serverList);
  67. }
  68.  
  69. public static void main(String[] args) throws Exception {
  70. // 获取连接
  71. DistributedClient client = new DistributedClient();
  72. client.getConn();
  73. // 获取子节点信息,并监听
  74. client.getServerList();
  75. // 启动业务功能
  76. client.handleBI();
  77. }
  78. }

大数据入门第二天——基础部分之zookeeper(下)的更多相关文章

  1. 大数据入门第二天——基础部分之zookeeper(上)

    一.概述 1.是什么? 根据凡技术必登其官网的原则,我们先去官网瞅一瞅:http://zookeeper.apache.org/ Apache ZooKeeper is an effort to de ...

  2. 大数据入门第一天——基础部分之Linux基础(环境准备与先导知识)

    一.Linux环境安装 1.VM的安装 参考Linux环境搭建随笔:http://www.cnblogs.com/jiangbei/p/7248054.html 2.CentOS的安装 同参考上述随笔 ...

  3. 大数据入门第二十二天——spark(一)入门与安装

    一.概述 1.什么是spark 从官网http://spark.apache.org/可以得知: Apache Spark™ is a fast and general engine for larg ...

  4. 大数据入门第二十五天——elasticsearch入门

    一.概述 推荐路神的ES权威指南翻译:https://es.xiaoleilu.com/010_Intro/00_README.html 官网:https://www.elastic.co/cn/pr ...

  5. 大数据入门第二十二天——spark(二)RDD算子(1)

    一.RDD概述 1.什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行计算的 ...

  6. 大数据入门第二十五天——logstash入门

    一.概述 1.logstash是什么 根据官网介绍: Logstash 是开源的服务器端数据处理管道,能够同时 从多个来源采集数据.转换数据,然后将数据发送到您最喜欢的 “存储库” 中.(我们的存储库 ...

  7. 大数据入门第二十四天——SparkStreaming(一)入门与示例

    一.概述 1.什么是spark streaming Spark Streaming is an extension of the core Spark API that enables scalabl ...

  8. 大数据入门第二十二天——spark(三)自定义分区、排序与查找

    一.自定义分区 1.概述 默认的是Hash的分区策略,这点和Hadoop是类似的,具体的分区介绍,参见:https://blog.csdn.net/high2011/article/details/6 ...

  9. 大数据入门第二十四天——SparkStreaming(二)与flume、kafka整合

    前一篇中数据源采用的是从一个socket中拿数据,有点属于“旁门左道”,正经的是从kafka等消息队列中拿数据! 主要支持的source,由官网得知如下: 获取数据的形式包括推送push和拉取pull ...

随机推荐

  1. ubuntu16.04安装网易云音乐

    源网址 对于网易,我只服云音乐,业界良心,用过的人都知道.我最喜欢的就是歌曲的评论功能,还有朋友圈子.里面有很多好段子,还有很多的好故事,基本上,不是分手,就是回忆初恋,还有吐槽的.我认为音乐带给人的 ...

  2. 【Java】多线程

    class RunnableDemo implements Runnable { private Thread t; private String threadName; RunnableDemo( ...

  3. Java 性能调优指南之 Java 集合概览

    [编者按]本文作者为拥有十年金融软件开发经验的 Mikhail Vorontsov,文章主要概览了所有标准 Java 集合类型.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文: 本 ...

  4. [WinCE | VS2008 | Solution] VS2008 building WinCE projects taking a long time

    1. Open C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets 2. Find pa ...

  5. 全局唯一ID生成器

    分布式环境中,如何保证生成的id是唯一不重复的? twitter,开源出了一个snowflake算法,现在很多企业都按照该算法作为参照,实现了自己的一套id生成器. 该算法的主要思路为: 刚好64位的 ...

  6. 固定UILabel宽度分行显示

    固定UILabel宽度分行显示 这种小伎俩估计都被用烂了,笔者给大家提供一个category文件,供大家简单设置哦. 各种富文本效果哦(普通文本也是可以用的呢): 3行,固定宽度200 2行,固定宽度 ...

  7. like a virgin

    like a virgin 编辑 <Like a Virgin>是美国歌手麦当娜·西科尼的第二张个人专辑,已于1984年11月12日由华纳唱片旗下发行. 1985年,Like a Virg ...

  8. VS2015 无法启动IIS Express Web服务器(已解决)

    VS2015 无法启动IIS Express Web服务器 首先说一下我遇到问题的情况.这个项目是在公司电脑创建的,运行一直是正常的.今天把项目拷贝回来做. 可是到自己的电脑上,运行就提示 无法启动I ...

  9. wk_06.md

    IO与文件操作 文件内建函数open 内建函数open提供了初始化输入/输出(I/O)操作的通用接口.open()内建函数成功打开文件后会返回一个文件对象.open函数的语法如下: open(file ...

  10. HashMap,LinkedHashMap和Hashtable类的深入剖析与理解

    上一篇文章写了一些关于HashMap以及HashMap的线程安全问题,这篇文章再来说说Map系列中HashMap,LinkedHashMap和Hashtable三者之间的差异以及该注意的地方. Has ...