zookeeper实现动态感知服务器上下线-阿里云开发者社区

开发者社区> 游客a74jvhcp7vclg> 正文

zookeeper实现动态感知服务器上下线

简介: 在实际的生产环境中我们一般都是集群环境部署的,同一个程序我们会部署在相同的几台服务器中,这时我们可以通过负载均衡服务器去调度,但是我们并不能很快速的获知哪台服务器挂掉了,这时我们就可以使用zookeeper来解决这个问题。
+关注继续查看


 在实际的生产环境中我们一般都是集群环境部署的,同一个程序我们会部署在相同的几台服务器中,这时我们可以通过负载均衡服务器去调度,但是我们并不能很快速的获知哪台服务器挂掉了,这时我们就可以使用zookeeper来解决这个问题。

zookeeper的动态感知

 动态感知其实利用的就是zookeeper的watch功能,我们先来看下常规的负载均衡服务器的结构

image.png

再来看下我们用zookeeper实现的结构

image.png

文字描述:

1.感知上线

 当服务器启动的时候通过程序知道后会同时在zookeeper的servers节点下创建一个新的短暂有序节点来存储当前服务器的信息。客户端通过对servers节点的watch可以立马知道有新的服务器上线了

2.感知下线

 当我们有个服务器下线后,对应的servers下的短暂有序节点会被删除,此时watch servers节点的客户端也能立马知道哪个服务器下线了,能够及时将访问列表中对应的服务器信息移除,从而实现及时感知服务器的变化。

代码实现

服务器端代码

package com.dpb.dynamic;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

/**
 * 服务器端代码
 * @author dengp
 *
 */
public class DistributedServer {

    private static final String connectString = "192.168.88.121:2181,192.168.88.122:2181,192.168.88.123:2181";
    private static final int sessionTimeout = 2000;
    private static final String parentNode = "/servers";

    private ZooKeeper zk = null;

    /**
     * 创建到zk的客户端连接
     * 
     * @throws Exception
     */
    public void getConnect() throws Exception {
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                // 收到事件通知后的回调函数(应该是我们自己的事件处理逻辑)
                System.out.println(event.getType() + "---" + event.getPath());
                try {
                    zk.getChildren("/", true);
                } catch (Exception e) {
                }
            }
        });

    }

    /**
     * 向zk集群注册服务器信息
     * 
     * @param hostname
     * @throws Exception
     */
    public void registerServer(String hostname) throws Exception {

        String create = zk.create(parentNode + "/server", hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println(hostname + "is online.." + create);

    }

    /**
     * 业务功能
     * 
     * @throws InterruptedException
     */
    public void handleBussiness(String hostname) throws InterruptedException {
        System.out.println(hostname + "start working.....");
        Thread.sleep(Long.MAX_VALUE);
    }

    public static void main(String[] args) throws Exception {

        // 获取zk连接
        DistributedServer server = new DistributedServer();
        server.getConnect();

        // 利用zk连接注册服务器信息
        server.registerServer(args[0]);

        // 启动业务功能
        server.handleBussiness(args[0]);
    }
}

客户端代码

package com.dpb.dynamic;

import java.util.ArrayList;
import java.util.List;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
/**
 * 客户端:通过zookeeper获取服务器地址
 * @author 波波烤鸭
 *
 */
public class DistributedClient {

    private static final String connectString = "192.168.88.121:2181,192.168.88.122:2181,192.168.88.123:2181";
    private static final int sessionTimeout = 2000;
    private static final String parentNode = "/servers";
    // 注意:加volatile的意义何在?
    private volatile List<String> serverList;
    private ZooKeeper zk = null;

    /**
     * 创建到zk的客户端连接
     * 
     * @throws Exception
     */
    public void getConnect() throws Exception {
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                // 收到事件通知后的回调函数(应该是我们自己的事件处理逻辑)
                try {
                    //重新更新服务器列表,并且注册了监听
                    getServerList();
                } catch (Exception e) {
                }
            }
        });

    }

    /**
     * 获取服务器信息列表
     * 
     * @throws Exception
     */
    public void getServerList() throws Exception {

        // 获取服务器子节点信息,并且对父节点进行监听
        List<String> children = zk.getChildren(parentNode, true);

        // 先创建一个局部的list来存服务器信息
        List<String> servers = new ArrayList<String>();
        for (String child : children) {
            // child只是子节点的节点名
            byte[] data = zk.getData(parentNode + "/" + child, false, null);
            servers.add(new String(data));
        }
        // 把servers赋值给成员变量serverList,已提供给各业务线程使用
        serverList = servers;
        
        //打印服务器列表
        System.out.println(serverList);
        
    }

    /**
     * 业务功能
     * 
     * @throws InterruptedException
     */
    public void handleBussiness() throws InterruptedException {
        System.out.println("client start working.....");
        Thread.sleep(Long.MAX_VALUE);
    }
    
    public static void main(String[] args) throws Exception {
        // 获取zk连接
        DistributedClient client = new DistributedClient();
        client.getConnect();
        // 获取servers的子节点信息(并监听),从中获取服务器信息列表
        client.getServerList();
        // 业务线程启动
        client.handleBussiness();
    }
}

测试

1.在zookeeper中的/下创建一个servers永久节点

[zk: localhost:2181(CONNECTED) 1] create /servers servers
Created /servers

1.启动三个服务器

image.pngimage.png

再启动另外两个

image.png

3.启动一个客户端

image.png

4.关闭一个服务器然后在新开一个服务器观察

关掉server01后客户端立马打印如下信息

image.png

更新了服务器列表,移除了server01

再开启一个server04服务器查看

image.png

客户端获取到了刚刚上线的服务器。

ok~本文到此结束。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10089 0
史上最便捷搭建 ZooKeeper 服务器的方法
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 什么是 ZooKeeperZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效、高可用的分布式协调服务,提供了诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知和分布式锁等分布式基础服务。
918 0
Giraph源码分析(一)— 启动ZooKeeper服务
作者 | 白松 【注:本文为原创,引用转载需与数澜联系。】 Giraph介绍: Apache Giraph is an iterative graph processing system built for high scalability.
1132 0
微服务引擎 ZooKeeper 版正式公测
在微服务和大数据领域,ZooKeeper 可以说是一个相当老牌的微服务引擎了,无论是在微服务领域的 「服务注册发现」 或「 配置管理」,还是在多个大数据平台级产品背后负责分布式协调,ZooKeeper 都起着至关重要的作用。
1562 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13892 0
springcloud之服务注册与发现(zookeeper注册中心)-Finchley.SR2版
新年第一篇博文,接着和大家分享springcloud相关内容;本次主要内容是使用cloud结合zookeeper作为注册中心来搭建服务调用,前面几篇文章有涉及到另外的eureka作为注册中心,有兴趣的朋友会回顾下上几篇文章。
4555 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
11893 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
7365 0
ZooKeeper做独立服务器运行(下)
ZooKeeper做独立服务器运行(下) 四、ZooKeeper Java客户端连接后的命令概述 键入help,可以看到有如下命令: 点击(此处)折叠或打开 connecthost:port ...
584 0
+关注
游客a74jvhcp7vclg
10余年开发架构经验,同时乐于技术分享!
332
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载