首先需安装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的进程运行完了进程就结束了,而没有表现出在等待服务器端事件,应该就是这个原因。