互联网架构-分布式协调工具Zookeeper-053:Zookeeper快速入门

1 基于Zookeeper实现动态负载均衡课程介绍

课程内容
1.Zookeeper的应用场景有那些
2.Zookeeper基本特性与数据模型
3.ZookeeperACL访问控制列表
4.Zookeeper实现动态负载均衡

2 Zookeeper实际案例中的应用场景

什么是Zookeeper
zookeeper是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
简单来说zookeeper(简称zk)=文件系统+监听通知机制。

Zookeeper应用场景
1.分布式锁
2.Dubbo服务注册(zk)
3.分布式配置中心disconfig
4.分布式消息中间件
5.发布订阅(事件通知)

3 Zookeeper基本的实现的特征

Zookeeper类似文件系统,基本特征:

  1. 定义的节点包含节点名称和节点内容,节点路径必须保证是唯一,不允许重复
  2. 每个节点都会有事件通知,当节点发生任何变化都可以获取到对应的信息;

4 基于linux环境安装Zookeeper

安装jdk环境1.8
1.安装jdk
cd /usr/local
上传jdk1.8安装包并解压tar -zxvf jdkxxxx
mv jdkxxxx jdk1.8
2.修改jdk1.8环境变量vi /etc/profile,文件末尾添加以下内容

export JAVA_HOME=/usr/local/jdk1.8
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

刷新profile文件 source /etc/profile
查看java是否安装成功 java -version

Linux环境安装Zookeeper
1.解压zk压缩包
cd /usr/local
上传zk安装包并解压tar -zxvf zookeeperxxxx
tar -zxvf zookeeperxxxx
mv zookeeperxxxx zookeeper
2. 进入到zk目录,在zk目录中创建data和logs文件夹
cd zookeeper
mkdir data
mkdir logs
3.进入到conf目录,修改配置文件
cd conf
mv zoo_sample.cfg zoo.cfg
vi zoo.cfg

dataDir =/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/logs

4.进入bin目录启动zk
./zkServer.sh start
./zkServer.sh status
单机启动成功
关闭防火墙systemctl stop firewalld
使用工具zktools连接
在这里插入图片描述

5 Java语言客户端连接Zookeeper

引入依赖

<dependencies>
    <!-- java语言连接zk -->
    <dependency>
        <groupId>com.101tec</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.8</version>
    </dependency>
</dependencies>

创建节点

public class Test001 {

    // 连接地址
    private static final String CONNECTIONS = "192.168.0.53:2181";
    // 超时时间
    private static final int TIMEOUT = 5000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        // zk核心:节点+事件通知
        // 1.创建zk连接
        ZooKeeper zk = new ZooKeeper(CONNECTIONS, TIMEOUT, watchedEvent -> {
            Watcher.Event.KeeperState state = watchedEvent.getState();
            if (state == Watcher.Event.KeeperState.SyncConnected) {
                System.out.println("zk连接成功");
            }
        });
        // 2.创建节点
        // 参数1:路径名称
        // 参数2:节点value
        // 参数3:节点权限acl
        // 参数4:节点类型 临时和持久
        String s = zk.create("/mayikt", "mayikt".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(s);
        zk.close();;
    }
}

运行结果:
在这里插入图片描述

6 Countdown计算器优化ZK代码

以上代码存在缺陷,如果zk创建失败执行create方法异常

使用CountDownLatch优化代码

public class Test002 {
    // 连接地址
    private static final String CONNECTIONS = "192.168.0.53:2181";
    // 超时时间
    private static final int TIMEOUT = 5000;
    // 计数器
    private static CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        // zk核心:节点+事件通知
        // 1.创建zk连接
        ZooKeeper zk = new ZooKeeper(CONNECTIONS, TIMEOUT, watchedEvent -> {
            Watcher.Event.KeeperState state = watchedEvent.getState();
            if (state == Watcher.Event.KeeperState.SyncConnected) {
                System.out.println("zk连接成功");
                // 计数器-1
                countDownLatch.countDown();
            }
        });
        // 计数器结果为0的情况才能继续执行
        System.out.println("zk正在连接等待...");
        countDownLatch.await();
        System.out.println("开始创建节点");
        // 2.创建节点
        // 参数1:路径名称
        // 参数2:节点value
        // 参数3:节点权限acl
        // 参数4:节点类型 临时和持久
        String s = zk.create("/mayikt2", "mayikt2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(s);
        zk.close();
    }
}

只有当zk创建成功,countDownLatch-1变为0,才能继续执行后面的代码,否则情况阻塞等待。
运行结果:
在这里插入图片描述

7 Zookeeper四种节点类型

zk节点分为四种类型:
1.临时节点CreateMode.EPHEMERAL
2.持久节点CreateMode.PERSISTENT
3.临时有序号节点(对名字自动做序列自增)CreateMode.EPHEMERAL_SEQUENTIAL
4.持久有序号节点(对名字自动做序列自增)CreateMode.PERSISTENT_SEQUENTIAL

创建节点必须先创建父节点,再创建子节点

8 Zookeeper节点ACL权限控制

ACL权限控制
ACL权限模型,实际上就是对每个节点实现控制
身份的认证有4种方式:
world:默认方式,相当于全世界都能访问
auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)
digest:即用户名:密码这种方式认证,这也是业务系统中最常用的
ip:使用ip地址认证

1.给节点设置权限

public class Test003 {
    public static void main(String[] args) throws Exception {
        // 1.创建zooKeeper连接
        ZooKeeper zooKeeper = new ZooKeeper("192.168.0.53", 500, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println(watchedEvent.getState().name());
            }
        });
        // 2.创建账号权限 admin可以实现读写操作
        Id id1 = new Id("digest", DigestAuthenticationProvider.generateDigest("admin:admin123"));
        ACL acl1 = new ACL(ZooDefs.Perms.ALL, id1);

        // 3.创建权限guest 只允许做读操作
        Id id2 = new Id("digest", DigestAuthenticationProvider.generateDigest("guest:guest123"));
        ACL acl2 = new ACL(ZooDefs.Perms.READ, id2);
        // 4.添加该账号
        ArrayList<ACL> aces = new ArrayList<ACL>();
        aces.add(acl1);
        aces.add(acl2);
        // 5.创建该节点
        String s1 = zooKeeper.create("/mayikt3", "mayikt3".getBytes(), aces, CreateMode.PERSISTENT);
        System.out.println("s1:" + s1);

    }
}

运行结果:
在这里插入图片描述
此时通过ZooInspector查询不到/mayikt3节点的值。

2.查询该节点必须授权账号

public class Test004 {
    public static void main(String[] args) throws Exception {
        // 1.创建zooKeeper连接
        ZooKeeper zooKeeper = new ZooKeeper("192.168.0.53", 500, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println(watchedEvent.getState().name());//SyncConnected
            }
        });
        // 2.设置zk连接账号
        zooKeeper.addAuthInfo("digest", "guest:guest123".getBytes());
        byte[] bytes = zooKeeper.getData("/mayikt3", null, new Stat());
        String string = new String(bytes);
        System.out.println(string);//mayikt3
    }
}

9 使用Zookeeper实现服务注册

在这里插入图片描述
服务注册

@Component
public class ApplicationRunnerImpl implements ApplicationRunner {
    // SpringBoot启动成功之后,执行的回调方法

    //参数1 连接地址
    private static final String ADDRES = "192.168.0.53:2181";
    // 参数2 zk超时时间
    private static final int TIMEOUT = 50000;
    // 计数器
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    @Value("${server.port}")
    private String serverPort;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        ZooKeeper zooKeeper = new ZooKeeper(ADDRES, TIMEOUT, watchedEvent -> {
            Watcher.Event.KeeperState state = watchedEvent.getState();
            if (state == Watcher.Event.KeeperState.SyncConnected) {
                System.out.println("zk连接成功");
                countDownLatch.countDown();
            }
        });
        countDownLatch.await();
        // 1. 判断父节点是否存在
        String parentPath = "/mayikt-service";
        Stat exists = zooKeeper.exists(parentPath, null);
        // 2. 创建子节点
        if (exists == null) {
            // 父节点不存在
            zooKeeper.create(parentPath, "mayikt".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        // 3.实现服务注册
        String pathValue = "http://127.0.0.1:" + serverPort;
        zooKeeper.create(parentPath + "/" + serverPort, pathValue.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.EPHEMERAL);
        System.out.println("服务注册成功" + parentPath);
    }
}

运行效果:
在这里插入图片描述

10 使用Zookeeper实现服务发现

public class ServiceDiscovery {

    private static final CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        ZooKeeper zooKeeper = new ZooKeeper("192.168.0.53:2181", 50000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                Event.KeeperState state = watchedEvent.getState();
                // 如果当前连接成功,则开始放心
                if (state == Event.KeeperState.SyncConnected) {
                    System.out.println("zk连接成功~~");
                    countDownLatch.countDown();
                }
            }
        });
        countDownLatch.await();
        String path = "/mayikt-service";
        // 获取该节点下子集
        List<String> children = zooKeeper.getChildren(path, null, new Stat());
        for (String c : children) {
            String pathChildren = path + "/" + c;
            byte[] data = zooKeeper.getData(pathChildren, null, new Stat());
            System.out.println("服务接口地址:" + new String(data));
        }
        /**
         * 运行结果:
         * zk连接成功~~
         * 服务接口地址:http://127.0.0.1:8080
         * 服务接口地址:http://127.0.0.1:8081
         */
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值