迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > PHP >

php zookeeper常见问题解决方案

作者:迹忆 最近更新:2022/12/11 浏览次数:

《PHP Zookeeper你需要知道的细节》(以下称为php_zk)一章中我们提出了问题,并且通过分析PHP-ZooKeeper源码找出了问题的原因,但是并没有给出解决方法。本章我们就来看一看解决的办法。

解决的办法分为两种:

一是修改PHP-ZooKeeper源码,重新编译安装
二是修改php代码

下面我们先来看第一种方式。

修改PHP-ZooKeeper源码

在php_zk一章中我们看到,其实在znode节点值为NULL的时候,使用php-zookeeper的get()方法能监听znode节点,但是并不能成功调用回调函数。原因就在于get()这个函数底层实现是当znode值为null的时候调用的函数如下

status = zoo_exists(i_obj->zk, path, 1, &stat);

但是我们可以看一下当znode有值的时候,它会调用到下面的函数

status = zoo_wget(i_obj->zk, path, (fci.size != 0) ? php_zk_watcher_marshal : NULL,
	          cb_data, buffer, &length, &stat);

所以我们分析php_zk_watcher_marshal是解析回调函数的,而在zoo_exists()中第三个参数为1,因此要想解决问题,必须要在zoo_exists()这个函数上找突破。继续进入zoo_exists()函数底层的定义发现其实该函数的实现也很简单

int zoo_exists(zhandle_t *zh, const char *path, int watch, struct Stat *stat)
{              
    return zoo_wexists(zh,path,watch?zh->watcher:0,zh->context,stat);
}

在它的底层又调用了zoo_wexists()函数。所以说我们完全可以在get()函数定义中将zoo_exists()函数改成zoo_wexists()。示例如下

if (max_size <= 0) {
    /*status = zoo_exists(i_obj->zk, path, 1, &stat);*/
    status =zoo_wexists(i_obj->zk,path,(fci.size!=0)?php_zk_watcher_marshal:NULL,cb_data,&stat);
    if (status != ZOK) {
	php_cb_data_destroy(&cb_data);
	php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
	return;

    }
    length = stat.dataLength;
} else {
    length = max_size;
}

这样一来,回调函数就会被执行了。

保存以后,重新编译安装就可以了

# ./configure --with-libzookeeper-dir=/opt/zk_c/ --with-php-config=/usr/local/php5/bin/php-config
# make
# make test
# make install

因为之前已经在php.ini中添加了zookeeper的配置,所以这里不用在进行任何配置。

完成以后再次按照php_zk文章中进行php代码的运行步骤就会发现能正常的进行新的leader的选举了。

修改php代码

虽然能修改PHP-ZooKeeper的源码来解决问题,但是没有十足的把握还是不要修改源码,因为这可能会影响到其它函数的使用。所以这里我们可以在php代码层来进行修改。

我们在php_zk一章中看到,在进行/cluster子节点的创建中使用的是下面的代码

$this->znode = $this->create(self::CONTAINER . '/w-', null, $this->acl, Zookeeper::EPHEMERAL | Zookeeper::SEQUENCE);

在$this->create()函数中,第三个参数是znode的值,这里我们默认为null。如果我们给他一个不为null的默认值的话,这个问题就迎刃而解了。如下示例

$this->znode = $this->create(self::CONTAINER . '/w-', '1', $this->acl, Zookeeper::EPHEMERAL | Zookeeper::SEQUENCE);

当然我们这里为了测试,只是简单的给了一个1。在实际场景中在创建节点的时候会根据实际应用来给出默认值,这里就暂且使用1来测试。

修改以后再次按照之前的步骤运行——不用在zookeeper客户端单独进行值的设置——就会发现也是能重新选出leader的。

以上两种方式我都是经过代码测试的,实践证明其可行。但是在实际中应该怎样去使用PHP-ZooKeeper都要根据场景去定。我这里只是抛砖引玉,指出在学习中的一些问题,希望能帮到各位。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

使用 PHP MySQLi 函数获取最后插入的 ID

发布时间:2023/05/09 浏览次数:85 分类:MySQL

本篇文章简要介绍了 PHP mysqli() 函数并演示了如何使用它从 MySQL 数据库中获取最后插入的 ID。它是一个名为 mysqli 的 MySQL 驱动程序扩展版本,

在 Mac 上编译 C 文件

发布时间:2023/05/07 浏览次数:157 分类:C语言

本篇文章介绍了如何在 MAC 操作系统上编译 .c 文件。在 Mac 操作系统上编译一个 .c 文件

适用于 Windows 的 C 编译器

发布时间:2023/05/07 浏览次数:163 分类:C语言

一篇关于适用于 Windows 平台的不同 C 编译器的文章。这篇简短的文章讨论了可用于 Windows 平台 C 语言编程的不同编译器和 IDE。

在 PHP 中使用 MongoDB 作为文件存储

发布时间:2023/04/20 浏览次数:133 分类:MongoDB

在为大文件创建可扩展存储方面,MongoDB 及其 GridFS(使用 MongoDB 查询语言 - MQL 编写)是市场上最好的文件存储解决方案之一。 在本教程中,您将学习如何在 PHP 中使用 MongoDB 作为文件存储。

如何在 PHP 中获取时间差的分钟数

发布时间:2023/03/29 浏览次数:183 分类:PHP

本文介绍了如何在 PHP 中获取时间差的分钟数,包括 date_diff()函数和数学公式。它包括 date_diff()函数和数学公式。

PHP 中的重定向

发布时间:2023/03/29 浏览次数:136 分类:PHP

本教程演示了如何将用户从页面重定向到 PHP 中的其他页面

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便