zookeeper管理数据库连接信息

zookeeper管理数据库连接信息


本文将讲解如何利用zookeeper来管理项目中的数据库连接信息,即将数据库的IP、账号密码等信息存储在zookeeper中,这样的好处是可以将多个工程的数据库连接集中管理,而zookeeper本事又是分布式的,所以可靠性又有保障。


一、安装zookeeper

1、下载zookeeper

可以通过官方网站或者国内镜像下载:

官方网站:http://zookeeper.apache.org/

上海大学开源社区镜像:http://mirrors.shuosc.org/apache/zookeeper/

本文使用的版本是 zookeeper-3.4.10,服务器为3台虚拟机,IP分别为192.168.1.191、192.168.1.192、192.168.1.193,先将安装包zookeeper-3.4.10.tar.gz 上传到192.168.1.191上。


2、修改配置文件

配置文件很简单,只需要一个配置文件 conf/zoo.cfg 和dataDir下的myid

先在192.168.1.191 所以zoo.cfg内容配置如下:

# The number of milliseconds of each tick  
tickTime=2000  
# The number of ticks that the initial   
# synchronization phase can take  
initLimit=5
# The number of ticks that can pass between   
# sending a request and getting an acknowledgement  
syncLimit=2
# the directory where the snapshot is stored.  
dataDir=/home/hadoop/zookeeper-3.4.10/data
# the port at which the clients will connect  
clientPort=2181  
server.1=192.168.1.191:2888:3888
server.2=192.168.1.192:2888:3888
server.3=192.168.1.193:2888:3888


参数说明:

tickTime: zookeeper中使用的基本时间单位, 毫秒值.

dataDir: 数据目录. 可以是任意目录.

dataLogDir: log目录, 同样可以是任意目录. 如果没有设置该参数, 将使用和dataDir相同的设置

clientPort: 监听client连接的端口号.

initLimit:follower和leader之间的最长心跳时间. 此时该参数设置为5, 说明时间限制为5倍tickTime, 即5*2000=10000ms=10s.

syncLimit: 该参数配置leader和follower之间发送消息, 请求和应答的最大时间长度. 此时该参数设置为2, 说明时间限制为2倍tickTime, 即4000ms.

server.I=A:B:C 其中I是一个数字, 表示这是第几号server. A是该server所在的IP地址. B配置该server和集群中的leader交换消息所使用的端口. C配置选举leader时所使用的端口. 如果配置的是伪集群模式, 则各个server的B, C参数必须不同.


/home/hadoop/zookeeper-3.4.10/data/myid内容为1即可,即只有一个数字1。

3、拷贝这个目录到其他两台机器192.168.1.192、192.168.1.193上,然后只需分别修改两台服务器上的/home/hadoop/zookeeper-3.4.10/data/myid文件内容为2和3即可


4、启动zookeeper

bin/zkServer.sh start

[hadoop@hadoop01 zookeeper-3.4.10]$ bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper-3.4.10/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

查看启动状态:

bin/zkServer.sh status

正常已启动状态如下:

ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.4.9/bin/../conf/zoo.cfg
Error contacting service. It is probably not running.

如果未启动,信息如下:

期中,Mode: follower表示从节点,Mode: leader表示主节点

ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: follower

需要分别在三台机器上启动

如果没有启动完全,就会报错

2017-10-06 16:44:36,114 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 192.168.1.191/192.168.1.191:2181. Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
2017-10-06 16:44:36,215 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@876] - Socket connection established to 192.168.1.191/192.168.1.191:2181, initiating session
JLine support is enabled
2017-10-06 16:44:36,268 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@1158] - Unable to read additional data from server sessionid 0x0, likely server has closed socket, closing socket connection and attempting reconnect
[zk: 192.168.1.191:2181(CONNECTING) 0] 2017-10-06 16:44:37,509 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 192.168.1.191/192.168.1.191:2181. Will not attempt to authenticate using SASL (unknown error)
2017-10-06 16:44:37,513 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@876] - Socket connection established to 192.168.1.191/192.168.1.191:2181, initiating session

或者

2017-10-06 16:44:08,360 [myid:] - INFO  [main-SendThread(192.168.1.193:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 192.168.1.193/192.168.1.193:2181. Will not attempt to authenticate using SASL (unknown error)
2017-10-06 16:44:08,386 [myid:] - WARN  [main-SendThread(192.168.1.193:2181):ClientCnxn$SendThread@1162] - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
java.net.ConnectException: 拒绝连接
        at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
        at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:361)
        at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1141)




5、连接zookeeper

bin/zkCli.sh -server 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181

[hadoop@hadoop01 zookeeper-3.4.10]$ bin/zkCli.sh -server 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181
Connecting to 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181
2017-10-06 16:47:24,330 [myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
2017-10-06 16:47:24,335 [myid:] - INFO  [main:Environment@100] - Client environment:host.name=hadoop01
2017-10-06 16:47:24,336 [myid:] - INFO  [main:Environment@100] - Client environment:java.version=1.8.0_131
2017-10-06 16:47:24,338 [myid:] - INFO  [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2017-10-06 16:47:24,339 [myid:] - INFO  [main:Environment@100] - Client environment:java.home=/home/hadoop/jdk1.8.0_131/jre
2017-10-06 16:47:24,339 [myid:] - INFO  [main:Environment@100] - Client environment:java.class.path=/home/hadoop/zookeeper-3.4.10/bin/../build/classes:/home/hadoop/zookeeper-3.4.10/bin/../build/lib/*.jar:/home/hadoop/zookeeper-3.4.10/bin/../lib/slf4j-log4j12-1.6.1.jar:/home/hadoop/zookeeper-3.4.10/bin/../lib/slf4j-api-1.6.1.jar:/home/hadoop/zookeeper-3.4.10/bin/../lib/netty-3.10.5.Final.jar:/home/hadoop/zookeeper-3.4.10/bin/../lib/log4j-1.2.16.jar:/home/hadoop/zookeeper-3.4.10/bin/../lib/jline-0.9.94.jar:/home/hadoop/zookeeper-3.4.10/bin/../zookeeper-3.4.10.jar:/home/hadoop/zookeeper-3.4.10/bin/../src/java/lib/*.jar:/home/hadoop/zookeeper-3.4.10/bin/../conf:.:/home/hadoop/jdk1.8.0_131/lib/tools.jar:/home/hadoop/jdk1.8.0_131/lib/dt.jar
2017-10-06 16:47:24,339 [myid:] - INFO  [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2017-10-06 16:47:24,340 [myid:] - INFO  [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2017-10-06 16:47:24,340 [myid:] - INFO  [main:Environment@100] - Client environment:java.compiler=<NA>
2017-10-06 16:47:24,340 [myid:] - INFO  [main:Environment@100] - Client environment:os.name=Linux
2017-10-06 16:47:24,340 [myid:] - INFO  [main:Environment@100] - Client environment:os.arch=amd64
2017-10-06 16:47:24,341 [myid:] - INFO  [main:Environment@100] - Client environment:os.version=2.6.18-274.el5
2017-10-06 16:47:24,341 [myid:] - INFO  [main:Environment@100] - Client environment:user.name=hadoop
2017-10-06 16:47:24,341 [myid:] - INFO  [main:Environment@100] - Client environment:user.home=/home/hadoop
2017-10-06 16:47:24,342 [myid:] - INFO  [main:Environment@100] - Client environment:user.dir=/home/hadoop/zookeeper-3.4.10
2017-10-06 16:47:24,344 [myid:] - INFO  [main:ZooKeeper@438] - Initiating client connection, connectString=192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@22d8cfe0
2017-10-06 16:47:24,402 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 192.168.1.191/192.168.1.191:2181. Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
2017-10-06 16:47:24,502 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@876] - Socket connection established to 192.168.1.191/192.168.1.191:2181, initiating session
JLine support is enabled
2017-10-06 16:47:24,556 [myid:] - INFO  [main-SendThread(192.168.1.191:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server 192.168.1.191/192.168.1.191:2181, sessionid = 0x15ef0dc89650001, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 0] 


6、查看当前节点

ls /

WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 1] ls /zookeeper
[zk2, zk, test, quota]

其他客户端命令可以用h查看

[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 2] h
ZooKeeper -server host:port cmd args
        stat path [watch]
        set path data [version]
        ls path [watch]
        delquota [-n|-b] path
        ls2 path [watch]
        setAcl path acl
        setquota -n|-b val path
        history 
        redo cmdno
        printwatches on|off
        delete path [version]
        sync path
        listquota path
        rmr path
        get path [watch]
        create [-s] [-e] path data acl
        addauth scheme auth
        quit 
        getAcl path
        close 
        connect host:port

7、创建新的节点

create [-s] [-e] path data acl

-s:指定该节点是一个序列节点,创建同名的节点时,会给节点自动加上编号 
-e:指定该节点是一个临时节点,默认是永久节点。临时节点会在客户端与服务器断开连接时,zk会将其创建的所有临时节点全部删除 
path:节点路径 
data:存储在节点中的数据 
acl:设置子节点访问权限,默认所有人都可以对该节点进行读写操作


如果使用-s参数,系统会自动在的节点名称后面加循环,如0000000007

[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 1] create -s /zookeeper/node xxx  
Created /zookeeper/node0000000007
[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 5] ls /zookeeper                     
[zk2, zk, test, dblink, node0000000007, quota]

这样并不是很方便,而且zkCli也没有通过修改节点名称的方法。那么,怎么样才能让他就用我们指定的名称呢?那就是create后面直接接节点名称,不加-s也不加-e。


[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 3] create /zookeeper/dblink xxxx
Created /zookeeper/dblink
[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 4] ls /zookeeper
[zk2, zk, test, dblink, quota]
[zk: 192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181(CONNECTED) 5] get /zookeeper/dblink
xxxx
cZxid = 0x300000006
ctime = Fri Oct 06 16:50:19 CST 2017
mZxid = 0x300000006
mtime = Fri Oct 06 16:50:19 CST 2017
pZxid = 0x300000006
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0



二、创建数据库连接信息

现在我们需要将数据库配置信息存放到zookeeper的节点中,但是,如果通过zkCli 会遇到一个问题,那就是zkCli没有转义,即没法写入换行符,比如我们的数据库配置信息:

userName=sa
userPwd=123
dbURL:jdbc:sqlserver://192.18.1.101:1433;DatabaseName=db1
driverNamecom.microsoft.sqlserver.jdbc.SQLServerDriver
所以, 必须通过zookeeper的API 来实现。需要引入的外部包  zookeeper-3.4.10.jar 和slf4j-api-1.6.1.jar在 zookeeper-3.4.10.tar.gz压缩包中都可以找到


            ZooKeeper zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher); //创建一个ZooKeeper对象
             
            zooKeeper.setData("/zookeeper/dblink", "userName=sa\nuserPwd=123".getBytes(),-1);  //通过zooKeeper.setData来修改节点数据



三、获取数据库连接信息

创建并配置好数据库连接信息后,即可通过getData方法来获取数据信息,然后通过Properties来解析信息


ZooKeeper zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher);  
            byte[] b = zooKeeper.getData(path, true, null) ;
            String res= new String(b);
            
            Properties pro = new Properties();
    		String userName =null;
    		String userPwd =null;
    		String dbURL =null;
    		String driverName =null;
    		try {
    			pro.load(new StringBufferInputStream(res));
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}


完整的java代码如下:

package Package1;

import org.apache.zookeeper.ZooKeeper;  
import org.apache.zookeeper.Watcher;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Reader;
import java.io.StringBufferInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import java.util.Properties;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Op.SetData;
import org.apache.zookeeper.WatchedEvent;



public class ZooKeeperDBlink {

	public static void main(String[] args) {  
		
		String data="dbURL=jdbc:sqlserver://192.168.1.101:1433;DatabaseName=db1\n"+
		"userName=sa\n"+
		"userPwd=123\n"+
		"driverName=com.microsoft.sqlserver.jdbc.SQLServerDriver";
		setData("/zookeeper/dblink",data);
		getDB();
		 
		
		 
    }
	
	
	public static void getDB(){
		String connectString = "192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181";  
		String path="/zookeeper/dblink";
        int sessionTimeout = 4000;  
        Watcher watcher = new Watcher() {  
            public void process(WatchedEvent event) {  
                //System.out.println(event.getPath());  
            }  
        }; 
        try {  
            ZooKeeper zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher);  
            byte[] b = zooKeeper.getData(path, true, null) ;
            String res= new String(b);
            
            Properties pro = new Properties();
    		String userName =null;
    		String userPwd =null;
    		String dbURL =null;
    		String driverName =null;
    		try {
    			pro.load(new StringBufferInputStream(res));
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		dbURL=pro.getProperty("dbURL");
    		userName=pro.getProperty("userName");
    		userPwd=pro.getProperty("userPwd");
    		driverName=pro.getProperty("driverName");
    		
    		System.out.println("userName:"+userName);
    		System.out.println("userPwd:"+userPwd);
    		System.out.println("dbURL:"+dbURL);
    		System.out.println("driverName"+driverName);

        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (KeeperException e) {  
            e.printStackTrace();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
 		
	}
	
	public static void setData(String path, String data){
		String connectString = "192.168.1.191:2181,192.168.1.192:2181,192.168.1.193:2181";  
        int sessionTimeout = 4000;  
        Watcher watcher = new Watcher() {  
            public void process(WatchedEvent event) {  
                //System.out.println(event.getPath());  
            }  
        }; 
        try {  
            ZooKeeper zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher); //创建一个ZooKeeper对象
             
            zooKeeper.setData(path, data.getBytes(),-1);  //通过zooKeeper.setData来修改节点数据
            
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (KeeperException e) {  
            e.printStackTrace();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
         
	}
	
	

}

输出结果:

userName:sa
userPwd:123
dbURL:jdbc:sqlserver://192.168.1.101:1433;DatabaseName=db1
driverNamecom.microsoft.sqlserver.jdbc.SQLServerDriver



猜你喜欢

转载自blog.csdn.net/cakecc2008/article/details/78165653