zoukankan      html  css  js  c++  java
  • 基于zookeeper实现统一资源管理

    分布式系统中经常涉及到配置资源的管理,比如,一个应用系统需要部署在多台服务器上,但是他们拥有某些的配置项是相同的,如果配置变更,需要修改这些配置,那么需要同时修改每台服务器,这样做比较麻烦而且容易出错。类似于这样的资源配置管理完全可以交给zookeeper进行管理,将需要配置的资源保存在zookeeper,当配置数据变化时,zookeeper会将变化信息发布到所有侦听zookeeper的服务器,服务器上的应用就可以从zookeeper中获取最新的配置信息。本文主要介绍如何通过Curator架构,使用zookeeper构建一个简单的配置资源管理系统。

    系统架构

    本文示例如下图所示,系统由三个部分组成,server端,zookeeper端和controller端,server端包含三个运行相同配置app的server,监听zookeeper中的conf节点。controller端用于操作zookeeper中的数据节点,当用户通过controller更新conf节点,三个server都会收到NodeDataChange消息。

    Code

    为演示简单起见,Serevr1, Srever2, Server3运行的代码一致,代码主要包含以下几个部分:

    1.zookeeper需要存储的数据bean,这里我们使用json对bean 对象进行序列化。

    package com.zte.zoo.keeper.configuration;
    
    /**
     * Created by majun on 15/10/29.
     */
    public class ConfigBean {
        private String url;
        private String port;
        private String name;
        private String pwd;
    
        public String getUrl() {
            return url;
        }
    
        public ConfigBean setUrl(String url) {
            this.url = url;
            return this;
        }
    
        public String getPort() {
            return port;
        }
    
        public ConfigBean setPort(String port) {
            this.port = port;
            return this;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public ConfigBean setPwd(String pwd) {
            this.pwd = pwd;
            return this;
        }
    
        public String getName() {
            return name;
        }
    
        public ConfigBean setName(String name) {
            this.name = name;
            return this;
        }
    
        @Override
        public String toString() {
            return GsonUtils.toJson(this);
        }
    }
    
    

    2.Server端运行的app code如下所示,主函数使用curatorwatch监听zookeeper的conf节点,当收到数据变化事件通知,打印

    public class Server{
        public static void main(String[] args) {
            private final String serverName="app2";
            final CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
            client.start();
            try {
                client.getData().usingWatcher(new CuratorWatcher() {
                    public void process(WatchedEvent watchedEvent) throws Exception {
                        if (Watcher.Event.EventType.NodeDataChanged == watchedEvent.getType()) {
                            String data = new String(client.getData().forPath(watchedEvent.getPath()));
                            System.out.println(serverName + " recv data:" + GsonUtils.fromJson(data, ConfigBean.class));
                        }
                    }
                }).forPath("/conf");
            } catch (Exception e) {
                e.printStackTrace();
            }
            while (true) ;
        }
    
    }
    

    3.Controller端运行的控制代码,更新zookeeper中具有PERSISTENT属性的conf节点

    public class Controller {
        public static void main(String[] args) throws Exception {
            CuratorFramework newClient = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
            newClient.start();
            ConfigBean configBean = new ConfigBean()
                    .setUrl("192.168.1.1")
                    .setPort("8000")
                    .setName("majun")
                    .setPwd("123");
    //        createNode(newClient, "/conf", CreateMode.PERSISTENT, configBean.toString());
    
            updateNodeDate(newClient,"/conf",configBean.setName("xiaoya--").toString());
        }
        public static void createNode(CuratorFramework newClient, String path, CreateMode createMode, String data) {
            try {
                newClient.create().withMode(createMode).forPath(path, data.getBytes());
            } catch (Exception e) {
                System.out.println("创建节点失败, elog=" + e.getMessage());
            }
        }
        public static void updateNodeDate(CuratorFramework newClient, String path, String data) {
            try {
                newClient.setData().forPath(path, data.getBytes());
            } catch (Exception e) {
                System.out.println("更新节点数据失败, elog=" + e.getMessage());
            }
        }
    
    }
    

    4.json序列化工具类

    public class GsonUtils {
        private static Gson gson = new Gson();
    
        public static String toJson(Object obj) {
            return gson.toJson(obj);
        }
        public static Object fromJson(String json, Class cla) {
            return gson.fromJson(json, cla);
        }
    }
    

    Test

    启动zookeeper, 使用controller中的创建节点函数创建conf节点,然后分别启动三个server,使用controller中的更新函数更新节点,会在三个server打印的更新数据信息。

    Conclusion

    本文和大家分享了如何基于curator框架使用zookeeper构建统一资源管理系统,希望能够对大家有所帮助。

  • 相关阅读:
    dataGridView不选中第一行第一列的办法!
    C#唯一随机数 和 PadLeft、PadRight 补足位数
    SSRS 数值和日期格式
    Oracle SQL*Loader
    找不到请求的 .Net Framework Data Provider。可能没有安装
    ORA00837: Specified value of MEMORY_TARGET greater than MEMORY_MAX_TARGET
    oracle临时表空间 ORA01652:无法通过16(在表空间XXX中)扩展 temp 字段
    ORACLE恢复删除表或表记录
    Spring.Net Resource handler for the 'web' protocol is not defined.
    ASP.NET MVC ueditor图片上传失败问题
  • 原文地址:https://www.cnblogs.com/jun-ma/p/4921005.html
Copyright © 2011-2022 走看看