Zookeeper的选举及运维可视化查看器及容灾

Zookeeper的选举及运维可视化查看器及容灾

每天多学一点点~
话不多说,这就开始吧…

1.Zookeeper的选举

上文 linux搭建zookeeper集群
咱们搭建了三个集群,分别是 192.168.73.131,192.168.73.132,192.168.73.133
选举分5个步骤:

  1. 初始化leader选举,投票
    给自己投票 myid zxid 0
  2. 每个服务器接受投票
    (1 0) (2,0) (3,0) >myid 谁最大谁就是leader
  3. 处理投票
    别的服务器 pk
  4. 统计投票
    过半票数n=n/2+1;
  5. 服务器状态变更
    Leader,其他票数低 f

依次启动三个zk,发现192.168.73.132是leader,其余两个是follower,这是因为
1: 三个服务器的myid分别是 1 2 3
2: 满足过半统计,即一共三个,启动第二个时候已经满足过半,所以第二个自动是leader
若 反过来启动,即 按照 133-132-131的顺序,则133是leader,因为 133的myid最大,且启动132时候已经满足过半,所以133是leader

2.Zookeeper的四字运维命令

ZooKeeper四字命令 功能描述
conf 3.3.0版本引入的。打印出服务相关配置的详细信息。
cons 3.3.0版本引入的。列出所有连接到这台服务器的客户端全部连接/会话详细信息。包括"接受/发送"的包数量、会话id、操作延迟、最后的操作执行等等信息。
crst 3.3.0版本引入的。重置所有连接的连接和会话统计信息。。
dump 列出那些比较重要的会话和临时节点。这个命令只能在leader节点上有用。
envi 打印出服务环境的详细信息。
reqs 列出未经处理的请求
ruok 测试服务是否处于正确状态。如果确实如此,那么服务返回"imok",否则不做任何相应。
stat 输出关于性能和连接的客户端的列表。
srst 重置服务器的统计。
srvr 3.3.0版本引入的。列出连接服务器的详细信息。
wchs 3.3.0版本引入的。列出服务器watch的详细信息。
wchc 3.3.0版本引入的。通过session列出服务器watch的详细信息,它的输出是一个与watch相关的会话的列表。
wchp 3.3.0版本引入的。通过路径列出服务器watch的详细信息。它输出一个与session相关的路径。
mntr 3.4.0版本引入的。输出可用于检测集群健康状态的变量列表

nc命令: Linux中nc命令是一个功能强大的网络工具,全称是netcat
在线安装:yum install -y nc
使用:echo zk命令|nc ip port
如:echo mntr |nc 192.168.73.131 2181
Zookeeper的选举及运维可视化查看器及容灾

3.自定义运维可视化工具

每次都要登陆服务器敲命令比较麻烦,那可不可以不登陆服务器,直接登陆网页就能查看呢?
既然可以在linux输入命令来查看zk集群状态,那么可不可以通过socket发送命令指令,再接收zk服务器的返回的信息,最后显示在页面上呢?想到这里,博主立马动手试了试。
为方便起见,博主直接用jsp页面画了个简单的雏形;springboot+jsp

  1. 在yml文件中配置zk集群
    mointor.zk1.host: 192.168.73.131
    mointor.zk2.host: 192.168.73.132
    mointor.zk3.host: 192.168.73.133
    mointor.zk.port: 2181

  2. controller层

package com.example.demo.controller;/**
 * @Classname MointorController
 * @Description TODO
 * @Date 2019/3/28 20:40
 * @Created by 爆裂无球
 */
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Map;

@Controller
@RequestMapping("/config")
public class MointorController {

   @Value("${mointor.zk1.host}")
   private String zk1;
   @Value("${mointor.zk2.host}")
   private String zk2;
   @Value("${mointor.zk.port}")
   private int port;

   @RequestMapping("/mointor/{command}")
   public String list(Map<String, Object> model, @PathVariable String command){
      try {
          String zk1=hander(command);
          model.put("zk1",zk1);
          model.put("zk2",zk1);
          model.put("zk3",zk1);
      } catch (IOException e) {
         e.printStackTrace();
      }
      return "mointer";
   }

   /**
    *  通过socker发送指令,接受 zk服务器返回的信息
    * @param command
    * @return
    * @throws IOException
    */
   public String hander(String command) throws IOException {
      Socket socket=new Socket(zk1,port);
      OutputStream outputStream=socket.getOutputStream();
      outputStream.write(command.getBytes());
      outputStream.flush();
      return IOUtils.toString(socket.getInputStream());


   }

}

  1. jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<html>
<html>
<head>
    <title>图灵学院</title>
</head>
<body>
<nav class="navbar navbar-default " role="navigation">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#" style="background: pink;">爆裂无球的zookeeper运维查看器</a>
        </div>

    </div>
</nav>

<body>
<h1>Zookeeper运维查看器</h1>
<a class="btn" href="conf">conf</a>
<a class="btn" href="cons">cons</a>
<a class="btn" href="crst">crst</a>
<a class="btn" href="dump">dump</a>
<a class="btn" href="envi">envi</a>
<a class="btn" href="ruok">ruok</a>
<a class="btn" href="srst">srst</a>
<a class="btn" href="srvr">srvr</a>
<a class="btn" href="stat">stat</a>
<a class="btn" href="wchs">wchs</a>
<a class="btn" href="wchp">wchp</a>
<a class="btn" href="mntr">mntr</a>

<table class="table table-striped">
    <tr style="font-weight:bold">
        <td>zk1</td>
        <td>zk2</td>
        <td>zk3</td>
    </tr>

        <tr>
            <td class="warning">${zk1}</td>
            <td class="warning">${zk2}</td>
            <td class="warning">${zk3}</td>
        </tr>

</table>

</body>

<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">

            <a class="navbar-brand" href="#" style="background: pink;">Burst No Ball</a>
        </div>

        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1" style="background: cornsilk;">

            <div style="line-height: 50px; text-align: center;font-size: 30px;">
                爆裂无球的zookeeper运维查看器
            </div>
        </div>
    </div>
</nav>

</html>
  1. 效果展示
    Zookeeper的选举及运维可视化查看器及容灾
    到这里,我们的可视化查看器就写完了,各位可以根据自己的需求继续完善

4.zk集群的容灾方案

如何保证高可用,跨机房如何部署,部署策略是什么?
若 zk集群一共有7台服务器,那么部署再几个机房比较好呢?若其中一个机房挂了怎么办?
三个机房,必须保证其中两个机房里面的服务器数量一样

  1. 3 3 1 :挂了其中任意一个,剩下的超过一半
  2. 2 2 3 :挂了其中任意一个,剩下的超过一半
    原则:半数以上,能选出leader

5.结语

世上无难事,只怕有心人,每天积累一点点,fighting!!!