首先需安装zookeeper的php扩展:http://pecl.php.net/package/zookeeper 

这是我最先写的demo,都符合zookeeper的api定义及行为定义。

#!/usr/bin/env php
<?php
if (!extension_loaded('zookeeper')) {
    die('zookeeper is required');
}

$host = 'localhost:2181';
$zk = new Zookeeper($host);

$zk->get('/bar', 'cb');

while( true ) { 
    echo '.';
    sleep(2);
}

function cb($event, $stat, $path)
{
    echo "in watch callback\n";
}

但当接收到服务器端的数据时,会报如下错误:

PHP Warning:  sleep(): could not invoke watcher callback in /Users/x/src/zoo-php/watch2.php on line 14
PHP Stack trace:
PHP   1. {main}() /Users/x/src/zoo-php/watch2.php:0
PHP   2. sleep() /Users/x/src/zoo-php/watch2.php:14

Warning: sleep(): could not invoke watcher callback in /Users/x/src/zoo-php/watch2.php on line 14

Call Stack:
    0.0012     227664   1. {main}() /Users/x/src/zoo-php/watch2.php:0
  754.5150     228272   2. sleep() /Users/x/src/zoo-php/watch2.php:14

这样的运行结果给我带来苦恼,代码应该是极简单的,然后在网上找了很多资料及官方的文档。找到一个可以正确运行的用例  https://github.com/andreiz/php-zookeeper/issues/34 ,这个用例和我的demo的差别仅是watch函数一个是简单的函数,一个是对象的方法。


我咨询过有经验人士,反馈说这可能是由于zookeeper的php扩展存在BUG,建议不要去浪费时间探究。


小结一下:进程在sleep系统调用上阻塞。曾经我以为进程在设置watcher的zookeeper的api上阻塞,如get、exists等,事实上不是。php-zookeeper扩展是使用C api封装的,其使用的多线程模型,至于线程在何处阻塞,不了解。有网友反馈用于watch的进程运行完了进程就结束了,而没有表现出在等待服务器端事件,应该就是这个原因。