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)比较然后交换。-》比较数据的版本号以后交换数据

  • 相关阅读:
    bzoj 1017 魔兽地图DotR
    poj 1322 chocolate
    bzoj 1045 糖果传递
    poj 3067 japan
    timus 1109 Conference(二分图匹配)
    URAL 1205 By the Underground or by Foot?(SPFA)
    URAL 1242 Werewolf(DFS)
    timus 1033 Labyrinth(BFS)
    URAL 1208 Legendary Teams Contest(DFS)
    URAL 1930 Ivan's Car(BFS)
  • 原文地址:https://www.cnblogs.com/leeSmall/p/9600959.html
Copyright © 2011-2022 走看看