ZooKeeper(配置管理)

ZooKeeper(配置管理)


配置的管理在分布式应用环境中很常见,例如同一个应用系统需要多台 PC Server 运行,但是它们运行的应用系统的某些配置项是相同的,如果要修改这些相同的配置项,那么就必须同时修改每台运行这个应用系统的 PC Server,这样非常麻烦而且容易出错。

像这样的配置信息完全可以交给 Zookeeper 来管理,将配置信息保存在 Zookeeper 的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。

本章主要是分布式环境下zookeeper配置管理,通过举例数据库的配置管理:
主要两个class,
SetConfig  主要是对节点设置配置。
ConfWatchClient 是节点拉去zookeeper的配置到本地。
package com.sw.config;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooKeeper.States;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;

public class SetConfig  implements Watcher{
	public static final String PATH = "/root/config";// 所要监控的结点
    private static ZooKeeper zk;

    private String CONF_AUTH = "digest";   //zk client auth
    private String CONF_PASSWD = "config:123456"; //zk client password

    private final static String URLNode = PATH + "/urlNode";
    private final static String userNameNode = PATH + "/userNode";
    private final static String passwordNode = PATH + "/passwdNode";

    public static void main(String[] args) {
		SetConfig setConfig = new SetConfig();
		setConfig.setValue();
	}

    public List<ACL> getAuth() throws NoSuchAlgorithmException{
    	List<ACL> acls = new ArrayList<ACL>(2);

    	Id id1 = new Id("digest", DigestAuthenticationProvider.generateDigest("admin:admin"));
    	ACL acl1 = new ACL(ZooDefs.Perms.ALL, id1);

    	Id id2 = new Id("digest", DigestAuthenticationProvider.generateDigest("guest:guest"));
    	ACL acl2 = new ACL(ZooDefs.Perms.READ, id2);

    	acls.add(acl1);
    	acls.add(acl2);

    	return acls;
    }

    public void setValue(){
    	String urlStr = "192.168.0.2";
    	String userStr = "admin";
    	String passwordStr = "admin";

    	ZooKeeper zk = this.initZk();

    	try {
    		if(zk.exists(PATH, true)==null){
                zk.create(PATH, urlStr.getBytes(), getAuth(), CreateMode.PERSISTENT);
 			}
			if(zk.exists(URLNode, true)==null){
               zk.create(URLNode, urlStr.getBytes(), getAuth(), CreateMode.PERSISTENT);
			}else {
				States stat = zk.getState();
				zk.setData(URLNode, "1.1.1.1".getBytes(), -1);
			}
			if(zk.exists(userNameNode, true)==null){
	            zk.create(userStr, urlStr.getBytes(), getAuth(), CreateMode.PERSISTENT);
			}
			if(zk.exists(passwordNode, true)==null){
	            zk.create(passwordStr, urlStr.getBytes(), getAuth(), CreateMode.PERSISTENT);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

    }


    public ZooKeeper initZk() {
		try {
			zk = new ZooKeeper("192.168.1.2:4181", 21810,this);
			zk.addAuthInfo(CONF_AUTH, CONF_PASSWD.getBytes()); //设置连接权限

		} catch (IOException e) {
			System.err.println("zk init connect fail" + e.getMessage());
		}
		return zk;
	}

	@Override
	public void process(WatchedEvent event) {
		// 主结点的数据发生改变时
        if (event.getType() == EventType.NodeDataChanged) {
        	System.err.println(event);
        }
        if (event.getType() == EventType.NodeDeleted){
        	System.err.println(event);
        }
        if(event.getType()== EventType.NodeCreated){
        	System.err.println(event);
        }
        if(event.getType()== EventType.NodeChildrenChanged){
        	System.err.println(event);
        }

	}



} 

package com.sw.config;

import java.io.IOException;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooKeeper;

import com.sw.WatchClient;

public class ConfWatchClient implements Watcher{
	private static final Logger logger = Logger.getLogger(WatchClient.class);

    public static final String PATH = "/root/config";// 所要监控的结点
    private static ZooKeeper zk;
    private static List<String> nodeList;// 所要监控的结点的子结点列表

    private String URL = "";
    private String userName = "";
    private String password = "";

    private String CONF_AUTH = "digest";   //zk client auth
    private String CONF_PASSWD = "config:123456"; //zk client password

    private final static String URLNode = PATH + "/urlNode";
    private final static String userNameNode = PATH + "/userNode";
    private final static String passwordNode = PATH + "/passwdNode";

	public static void main(String[] args) throws Exception {
		ConfWatchClient client = new ConfWatchClient();
		client.initZk();
        client.getConfig();

    }

	public void initConfig(){
        try {
			URL = new String(zk.getData(URLNode, true, null),"utf-8");
			userName = new String(zk.getData(userNameNode, true, null),"utf-8");
			password = new String(zk.getData(passwordNode, true, null),"utf-8");

			System.err.println("URL:"+URL+","+"userName:"+userName+",password:"+password);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ZooKeeper initZk() {
		try {
			zk = new ZooKeeper("192.168.1.2:4181", 21810,this);
			zk.addAuthInfo(CONF_AUTH, CONF_PASSWD.getBytes()); //设置连接权限

		} catch (IOException e) {
			System.err.println("zk init connect fail" + e.getMessage());
		}
		return zk;
	}

	public void getConfig() {
	    try {
			 /**
	         * 持续监控
	         */
	        while (true) {
	            try {
	                zk.exists(PATH, this);//所要监控的主结点
	                nodeList = zk.getChildren(PATH, this);

	                System.err.println(nodeList);

	                Thread.sleep(5000);// sleep一会,减少CUP占用率

	            } catch (KeeperException | InterruptedException e) {
	    			System.err.println(e.getMessage());
	            }
	        }

		} catch (Exception e) {
			e.getStackTrace();
		}

	}

	public void process(WatchedEvent event) {
        // 主结点的数据发生改变时
        if (event.getType() == EventType.NodeDataChanged) {
        	System.err.println(event);
        	initConfig();
        }
        if (event.getType() == EventType.NodeDeleted){
        	System.err.println(event);
        }
        if(event.getType()== EventType.NodeCreated){
        	System.err.println(event);
        }
        if(event.getType()== EventType.NodeChildrenChanged){
        	System.err.println(event);
        	initConfig();
        }
	}


	public String getURL() {
		return URL;
	}

	public void setURL(String uRL) {
		URL = uRL;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}