zoukankan      html  css  js  c++  java
  • Zookeeper系列五:Master选举、ZK高级特性:基本模型

    一、Master选举

    1. master选举原理:

    有多个master,每次只能有一个master负责主要的工作,其他的master作为备份,同时对负责工作的master进行监听,一旦负责工作的master挂掉了,其他的master就会收到监听的事件,从而去抢夺负责工作的权利,其他没有争夺到负责主要工作的master转而去监听负责工作的新master。

    本质其实是利用zookeeper的临时节点的特性:临时节点随着会话的消亡二消亡,同一个临时节点只能创建一个,创建失败的节点(从master)对创建成功节点(主master)进行监控,一旦创建成功的节点(主master)会话消失,之前创建失败的节点(从master)就会监听到去抢夺创建临时节点

    2. 代码实现-两个tomcat模拟master选举

    2.1 准备工作:

    1)首先在新建一个maven项目ZK-Demo,然后在pom.xml里面引入zk的依赖

            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.10</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>4.0.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>4.0.0</version>
            </dependency>
            
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-catalina</artifactId>
                <version>7.0.39</version>
            </dependency>

     2)在eclipse里面配置两个tomcat,具体方法百度

    注意:这里的两个tomcat的命名不规范,端口分别为8080,8081

    2.2 编写选举master的业务类

    package com.study.demo.election;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    
    import org.apache.catalina.connector.Request;
    import org.apache.catalina.connector.Response;
    import org.apache.catalina.valves.ValveBase;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.recipes.cache.TreeCache;
    import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
    import org.apache.curator.framework.recipes.cache.TreeCacheListener;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.CreateMode;
    
    /**
    * 
    * @Description: 两个tomcat模拟master选举
    * @author liguangsheng
    * @date 2018年9月6日
    *
    */
    public class ZkTomcatMaster extends ValveBase {
    
        private static CuratorFramework client;
        // zk临时节点路径(主master)
        private final static String zkPath = "/Tomcat/ActiveLock";
        //Curator事件监听
        private static TreeCache cache;
    
        @Override
        public void invoke(Request request, Response response) throws IOException, ServletException {
            client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181").connectionTimeoutMs(1000)
                    .retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
            client.start();
    
            try {
                createZKNode(zkPath);
            } catch (Exception e1) {
                System.out.println("=========== 抢夺成为master失败,对master进行监控!");
                try {
                    addZKNodeListener(zkPath);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        //创建临时节点zkPath = "/Tomcat/ActiveLock"
        private void createZKNode(String path) throws Exception {
            client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
            System.out.println("=========== 创建成功,节点当选为master");
        }
    
        //创建临时节点zkPath = "/Tomcat/ActiveLock"失败时对创建成功的节点(主master)进行监听
        private void addZKNodeListener(final String path) throws Exception {
            cache = new TreeCache(client, path);
            cache.start();
            cache.getListenable().addListener(new TreeCacheListener() {
                public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
                    if (event.getData() != null && event.getType() == TreeCacheEvent.Type.NODE_REMOVED) {
                        System.out.println("=========== master挂了,赶紧抢master权限!");
                        createZKNode(path);
                    }
                }
            });
            
            System.out.println("=========== 已经对master进行监控");
        }
    }

    2.3  在eclipse里面将ZkTomcatMaster.java打包成zkTomcatMaster.jar放到两个tomcat的lib目录下

    E:apache-tomcat-8.5.33lib

    E:softwareapache-tomcat-7.0.63lib

    同时还要向lib目录下放入相关依赖的包:

    zkTomcatMaster.jar
    
    相关依赖的包:
    curator-client-4.0.0.jar
    curator-framework-4.0.0.jar
    curator-recipes-4.0.0.jar
    zookeeper-3.4.10.jar
    jline-0.9.94.jar
    netty-3.10.5.Final.jar
    slf4j-api-1.6.1.jar
    slf4j-log4j12-1.6.1.jar
    selenium-server-standalone-2.44.0.jar
    javax.servlet-api-3.1.0.jar
    tomcat-catalina-7.0.39.jar
    log4j-1.2.14.jar

     需要这些包的朋友私聊我哈!

    2.4 在两个tomcat的server.xml里面加入如下配置:

    <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
        此处省略n行配置.....
        <Valve className="com.study.demo.election.ZkTomcatMaster"/>
     </Host>

     2.5 分别运行两个tomcat查看效果

    先运行Tomcat8.5 8080

    再运行tomcat8080

    2.6 停掉Tomcat8.5 8080观察tomcat8080的情况

    说明:这里是之前对Tomcat8.5 8080(主master的监听器作用了)

     2.7 再次启动Tomcat8.5 8080

     

    二、ZK高级特性:基本模型

    1. Zookeeper的数据模型—节点

    树模型(采用文件系统的形式,只不过去掉文件和目录),叫数据节点。

    2. ACL—权限控制

    2.1 对于一个节点可操作的权限有5种

    READ(只读)
    WRITE(只写)
    CREATE(创建)
    DELETE(删除)
    ADMIN(节点管理权限)
    All = READ|WRITE|CREATE|DELETE|ADMIN(所有权限)

    ACL机制:权限模式(Schema)、授权对象(ID)、权限(Permission)

    1)world:开放模式。意思所有人都可以访问。
    2)IP: 针对某个IP开放权限
    3)digest:用户/密码模式
    4)Super:超级用户模式

    2.2 设置节点权限

    使用密文语法:setAcl path digest|ip:username:password:c|d|r|w|a

    示例:
    1)用户名和加密密码的方式:

    创建test节点:

    create /test 123

    设置权限前先对密码进行加密(执行目录在zk根目录):

    cd /software/zookeeper-3.4.6
    java -cp ./zookeeper-3.4.6.jar:./lib/log4j-1.2.16.jar:./lib/slf4j-api-1.6.1.jar:./lib/slf4j-log4j12-1.6.1.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider user1:123456

    加密后的密文:

    user1:123456->user1:HYGa7IZRm2PUBFiFFu8xY2pPP/s=

    设置权限:

    setAcl /test digest:user1:HYGa7IZRm2PUBFiFFu8xY2pPP/s=:crwa

    使用明文增加认证才可以访问:
    语法:

    addauth digest username:password

    eg:

    addauth digest user1:123456

    2)IP的方式 setAcl /test ip:192.168.152.1:cdra

    设置以后,只有192.168.152.1才能访问

    3)使用明文设置权限(设置完以后可以直接使用 ls /test查看,不会像密文设置时查看提示没有权限):

    语法:

    setAcl /path auth:username:password:cdrwa

    eg:

    删除直接的/test节点并重新创建

    delete /test
    create /test 123

    设置权限

    setAcl /test auth:user1:123456:cdrwa

    说明:

    这里的删除得使用delete命令,rmr命令删除不了,会提示没有权限

    2.3 查看节点的权限

    语法:

    getAcl path

    2.4 节点的版本

    执行ls2  /test可看到如下信息

    cversion 当前节点的权限
    dataversion 当前节点数据内容的版本号
    aclVersion  就是ACL版本号

    说明:

    zookeeper版本的含义:版本指的是变更的次数。
    CAS(compare and swap)比较然后交换。-》比较数据的版本号以后交换数据

  • 相关阅读:
    JS 和 CSS 的位置对其他资源加载顺序的影响
    How browsers workBehind the scenes of modern web browsers
    Gruntjs入门 (2)
    Superhero.js – 构建大型 JavaScript 应用程序的最佳资源
    利用位反操作来简化 indexOf 判断
    Gruntjs入门 (1)
    js和css的顺序关系
    (翻译)理解JavaScript函数调用和"this"(by Yehuda Katz)
    秒,微秒,毫秒
    您试图从目录中执行 CGI、ISAPI 或其他可执行程序,但该目录不允许执行程序
  • 原文地址:https://www.cnblogs.com/leeSmall/p/9600959.html
Copyright © 2011-2022 走看看