C++实现zookeeper主从切换

1.下载zk

2.配置zk

       查看有无java环境。

       java -version

       安装java环境。

       yum list java* 查看yum源的java包。

       yum -y install java-1.8.0-openjdk 安装java包。

       在/usr/local/zookeeper下解压压缩包,解压后的文件夹重命名为zookeeper-3.5.5,进入zookeeper-3.5.5/conf目录,重命名zoo_sample.cfg为zoo.cfg,打开zoo.cfg,修改红色部分为dataDir=/usr/local/zookeeper/ zookeeper-3.5.5/data,并增加灰色底色部分。

       # the directory where the snapshot is stored.

       # do not use /tmp for storage, /tmp here is just

       # example sakes.

       dataDir=/tmp/zookeeper

       dataLogDir=/usr/local/zookeeper/zookeeper-3.5.5/logs

 

       将 zookeeper 的根目录设置到系统环境变量 PATH 中:

       sudo vi /etc/profile

       在打开的 profile 文件末尾追加如下配置:

       export ZOOKEEPER_HOME=/usr/local/zookeeper/zookeeper-3.5.5

       export PATH=$ZOOKEEPER_HOME/bin:$PATH

       export PATH

       保存并退出 vi;

       刷新 profile 文件使之立即生效:

       source /etc/profile

3.启动zk

        进入apache-zookeeper-3.5.5-bin/bin目录,执行:

        sh ./zkServer.sh start

4.C++包含的头文件和库

  1. 下载
  2. 解压后进入目录:apache-zookeeper-3.5.5/zookeeper-client/zookeeper-client-c
  3. 执行命令:

        autoreconf -if

        ./configure --disable-shared --without-cppunit

        make

       make install

        编译C lib库

  1. 编译后头文件为:/usr/local/include/zookeeper/zookeeper.h
  2. 编译后静态库文件为:/usr/local/lib/libzookeeper_mt.a
  3. 程序makefile需要引用zookeeper.h, libzookeeper_mt.a才能编译通过。

       -bash: autoreconf:未找到命令:

       yum  -y install install autoconf automake libtool

 

server.h

#include 
#include 
#include 
#include 
#include 

using namespace std;

class Server
{
public:
    Server(string path, string data, int timeout);
    ~Server();
    int connect_zk(const char *host);
    int create_zk_nodes();
    void start_work();  

private:
    void work();
    void run_for_master();
    void regist_master();
    static void zk_watcher(zhandle_t *zh, int type, int state, const char  *path,void *watcherCtx);
    static void node_watcher(zhandle_t *zh, int type, int state, const char  *path,void *watcherCtx);

private:
    string m_strNodePath;  
    string m_strNodeData;  
    int m_iRecvTimeout;	   
    zhandle_t *m_zkHandle; 
    struct String_vector m_path_info;
    volatile bool m_connect;
    volatile bool m_run;
};

server.cpp

#include "server.h"

Server::Server(string path, string data, int timeout)
{
    m_strNodePath = path;
    m_strNodeData = data;
    m_iRecvTimeout = timeout;
    m_run = false;
    m_connect = false;
    m_zkHandle = NULL;
}

Server::~Server()
{
    if(NULL != m_zkHandle)
    {
        zookeeper_close(m_zkHandle);
    }
}

int Server::connect_zk(const char *host)
{
    m_zkHandle = zookeeper_init(host, zk_watcher, m_iRecvTimeout, 0, this, 0);

    while(!m_connect)
    {
        sleep(1);
    }

    if (NULL == m_zkHandle)
    {
        cout << "zookeeper_init(): function return NULL!" << endl;
        return -1;
    }
    else
    {
        return 0;
    }
}

int Server::create_zk_nodes()
{
    char buf[256] = {0};
    int errcode = zoo_create(m_zkHandle, m_strNodePath.c_str(),
    	                       m_strNodeData.c_str(), static_cast(m_strNodeData.size()),
    	                          &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL|ZOO_SEQUENCE, buf, 256);
    if (errcode != ZOK)
    {
    	cout << "create_zk_nodes():Failed to create zk node!" << endl;
    	return -1;
    }
    else
    {
        m_strNodePath = string(buf);
        return 0;
    }
}

void Server::zk_watcher(zhandle_t *zh, int type, int state, const char  *path,void *watcherCtx)
{
    Server *pthis = (Server*)watcherCtx;
    if (type == ZOO_SESSION_EVENT) 
    {
        if (state == ZOO_CONNECTED_STATE) 
        {
            pthis->m_connect = true;
            cout << "Connected to zookeeper service successfully!" << endl;
        } 
    }
}

void Server::start_work()
{
    run_for_master();

    if (!m_run)
    {
        cout << "become slave" << endl;
    }

    int ret = zoo_wget_children(m_zkHandle, "/", node_watcher, this, &m_path_info);
    if (ret != 0)
    {
        cout << "get nodelist failed!" << endl;
    }

    while (!m_run)
    {
        sleep(1);
    }

    deallocate_String_vector(&m_path_info);
    cout << "become master" << endl;

    work();
}

void Server:: node_watcher(zhandle_t *zh, int type, int state, const char  *path,void *watcherCtx)
{
    sleep(3);
    Server *pthis = (Server*)watcherCtx;

    if (type == ZOO_CHILD_EVENT)
    {
        pthis->run_for_master();
    }
}

void Server::run_for_master()
{
    int ret = zoo_wget_children(m_zkHandle, "/", node_watcher, this, &m_path_info);
    if (0 != ret)
    {
        cout << "node_watcher(): update path error!" << endl;
    }

    string pathstr;
    pathstr.assign(m_strNodePath, 1, 15);
    char *minstr = new char[16];
    char *p = minstr;
    strcpy(minstr,pathstr.c_str());

    for (int i=0, len=m_path_info.count; i 0
            && strcmp("master",*(m_path_info.data + i)) != 0)
        {
            minstr = *(m_path_info.data + i);
        }
    }

    if (strcmp(minstr,pathstr.c_str()) == 0 
        && zoo_wexists(m_zkHandle, "/master", zk_watcher, NULL, NULL) == ZNONODE)
    {
        regist_master();
    }

    deallocate_String_vector(&m_path_info);
    delete []p;
    p = NULL;
}

void Server::regist_master()
{
    int errorcode = zoo_create(m_zkHandle, "/master", NULL, 0,
                &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, NULL, 0);

    if (ZOK == errorcode)
    {
        m_run = true;
    }
    else if (ZNODEEXISTS == errorcode)
    {
        cout << "regist_master():master is exist!" << endl;
    }
    else
    {
        cout << "regist_master():other error!" << endl;
    }
}

void Server:: work()
{
    while (1)
    {
        cout << "hello" << endl;
        sleep(2);
    }
}

main.cpp

#include "server.h"

int main(int argc, char *argv[])
{
    zoo_set_debug_level( ZOO_LOG_LEVEL_ERROR );
    const char *host = "127.0.0.1:2181";
    string path = "/nodes";
    string data = "nothing";
    int timeout = 10000;
    Server server(path, data, timeout);
    if (-1 == server.connect_zk(host))
    {
        return -1;
    }
    if (-1 == server.create_zk_nodes())
    {
        return -1;
    }
    server.start_work();
    getchar();
    return 0;
}

makefile

FLAGS = -g -I/user/local/include/zookeeper
CLIBS = -lzookeeper_mt -DTHREADED -lpthread

result: server.o main.o
	g++ $(FLAGS) server.o main.o -o result $(CLIBS)

main.o:main.cpp server.h
	g++ -g -c main.cpp

server.o:server.cpp server.h
	g++ -g -c server.cpp $(CLIBS)

clean:
	rm *.o 

 

你可能感兴趣的:(C++实现zookeeper主从切换)