基于zookeeper的主备切换方法
基于zookeeper的主备切换方法
zookeeper的ZOO_EPHEMERAL节点(如果ZOO_EPHEMERAL满足不了需求,可以考虑和ZOO_SEQUENCE结合使用),在会话关闭或过期时,会自动删除,利用这一特性可以实现两个或多节点间的主备切换。实现方法:
1)在进程启动时调用zookeeper_init()初始化:
bool X::init_zookeeper()
{
// 第一次调用时_clientid总是为NULL,
// 状态为ZOO_EXPIRED_SESSION_STATE时,需要重新调用zookeeper_init,
// 这个时候可传入的_clientid为前一次zookeeper_init()产生的_clientid
// 请注意zookeeper_init()是一个异步调用,返回非NULL并不表示会话建立成功,
// 只有当zk_watcher中的type为ZOO_SESSION_EVENT和state为ZOO_CONNECTED_STATE时,
// 才真正表示会话建立成功。
_zhandle = zookeeper_init(zk_hosts, zk_watcher, 5000, _clientid, this, 0);
if (NULL == _zhandle)
{
MYLOG_ERROR("init zookeeper failed: %s\n", zerror(errno));
return false;
}
MYLOG_INFO("init zookeeper(%s) successfully\n", zk_hosts);
return true;
}
2)进入工作之前,先尝试切换成主,只有成功切换成主后才进入work
bool X::run()
{
while (true)
{
int num_items = 0;
// 备机最简单的方法是每隔一定时间,如1秒就尝试转成master,
// 如果不使用轮询,则可以采用监视_zk_path的方式
mooon::sys::CUtils::millisleep(1000);
// 如果不是master,则尝试转成master,如果转成不成功则继续下一次尝试
if (!is_master() && !change_to_master())
continue;
do_work();
}
}
bool X::is_master() const
{
return _is_master;
}
bool X::change_to_master()
{
static uint64_t log_counter = 0; // 打log计数器,备状态时的日志输出
// ZOO_EPHEMERAL|ZOO_SEQUENCE
// _myip为本地IP地址,可以通过它来判断当前谁是master
// _zk_path值示例:/master/test,注意需要先保证/master已存在
int errcode = zoo_create(_zhandle, _zk_path.c_str(), _myip.c_str(), _myip.size()+1, &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, NULL, 0);
// (-4)connection loss,比如为zookeeper_init()指定了无效的hosts(一个有效的host也没有)
if (errcode != ZOK)
{
_is_master = false;
// 减少为备状态时的日志输出
if (0 == log_counter++ % 600)
{
MYLOG_DEBUG("become master[%s] failed: (%d)%s\n", _zk_path.c_str(), errcode, zerror(errcode));
}
return false;
}
else
{
_is_master = true;
log_counter = 0;
MYLOG_INFO("becase master[%s]\n", _zk_path.c_str());
// sleep一下,以便让原master正在进行的完成
mooon::sys::CUtils::millisleep(2000);
return true;
}
}
3)当zookeeper会话成功建立或过期时均会触发zk_watcher,可通过type和state来区分
void zk_watcher(zhandle_t *zh, int type, int state, const char *path, void *context)
{
X* x = static_cast
MYLOG_DEBUG("zh=%p, type=%d, state=%d, context=%p, path=%s\n", zh, type, state, context, path);
// zookeeper_init成功时type为ZOO_SESSION_EVENT,state为ZOO_CONNECTED_STATE
if ((ZOO_SESSION_EVENT == type) && (ZOO_CONNECTED_STATE == state))
{
x->on_zookeeper_connected(path);
}
else if ((ZOO_SESSION_EVENT == type) && (ZOO_EXPIRED_SESSION_STATE == state))
{
// 需要重新调用zookeeper_init(),简单点可以退出当前进程重启
x->on_zookeeper_expired();
}
}
附: zookeeper日志
默认情况下zookeeper日志是输出到stderr,但可以通过zoo_set_log_stream()来定向到自己的日志输出中,还可以使用zoo_set_debug_level()来控制zookeeper的日志级别。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

最近几天,Ice Universe 不断披露有关 Galaxy S25 Ultra 的详细信息,人们普遍认为这款手机将是三星的下一款旗舰智能手机。除此之外,泄密者声称三星只计划升级一款相机

OnLeaks 现在与 Android Headlines 合作,首次展示了 Galaxy S25 Ultra,几天前,他试图从他的 X(以前的 Twitter)粉丝那里筹集到 4,000 美元以上的资金,但失败了。对于上下文,嵌入在 h 下面的渲染图像

除了发布两款新智能手机外,TCL 还发布了一款名为 NXTPAPER 14 的新 Android 平板电脑,其大屏幕尺寸是其卖点之一。 NXTPAPER 14 采用 TCL 标志性品牌哑光液晶面板 3.0 版本

最近几天,Ice Universe 不断披露有关 Galaxy S25 Ultra 的详细信息,人们普遍认为这款手机将是三星的下一款旗舰智能手机。除此之外,泄密者声称三星只计划升级一款相机

Vivo Y300 Pro刚刚全面亮相,它是最薄的中端Android手机之一,配备大电池。准确来说,这款智能手机的厚度仅为 7.69 毫米,但配备了 6,500 mAh 的电池。这与最近推出的容量相同

三星尚未就何时更新其 Fan Edition (FE) 智能手机系列提供任何提示。目前来看,Galaxy S23 FE 仍然是该公司的最新版本,于 2023 年 10 月年初推出。

Redmi Note 14 Pro Plus 现已正式成为去年 Redmi Note 13 Pro Plus 的直接后继产品(亚马逊售价 375 美元)。正如预期的那样,Redmi Note 14 Pro Plus与Redmi Note 14和Redmi Note 14 Pro一起成为Redmi Note 14系列的主角。李

摩托罗拉今年发布了无数设备,尽管其中只有两款是可折叠的。就上下文而言,虽然世界上大多数地区都收到了 Razr 50 和 Razr 50 Ultra,但摩托罗拉在北美提供了 Razr 2024 和 Razr 2
