php+nodeJs+thrift协议,实现zookeeper节点数据自动发现
内容导读
收集整理的这篇技术教程文章主要介绍了php+nodeJs+thrift协议,实现zookeeper节点数据自动发现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6046字,纯文字阅读大概需要9分钟。
内容图文
php是当下最流行的web服务器端语言,zookeeper是大型分布式协同工具,本文在这里介绍一种架构实现php服务器对于zookeeper数据变化的自动监听。一.问题背景
php可以CLI模式模式连接zookeeper(下面简称zk),并实现zk节点数据的自动发现,这里不做过多叙述。但web服务器中,php只能主动连接zk以获得节点数据,做不到zk数据的自动发现。其次,php web服务,也难以和php CLI模式下的服务共享数据变量(cli模式下zk数据做成共享变量)。这就导致如果并发量大的话,每一个http请求php都会去连接zk,zk集群的压力会很大,其次,每一个请求都会连接zk,请求结束又释放zk连接,zk的连接与释放过于频繁。
二.解决思路
nodeJs多进程间可以通信,可以解决php服务难以实现共享变量的问题。nodeJs可以在主进程中抛出一个子进程,子进程中实现zk的自动发现,子进程侦察到zk节点数据变化时,主动通知主进程。node主进程写一个服务,像外界提供zk的数据。php web服务需要zk节点数据时,通过RPC协议(这里使用thrift协议),访问本地node主进程服务,来获取zk节点数据。
这样做有三点好处:
1.实现zk节点变化的自动发现;
2.php和node通信在同一台服务器上,不走网管,速度快,稳定性可靠
3.thrift协议直接操作套接字传输数据,比http服务要快,可以近似看作php调用自己的方法
三.具体实现
1.搭建zookeeper服务,这里我搭了一个5台zk服务的伪集群(zk服务的搭建这里不做过多介绍),测试zk服务是否能正常写入与读取节点数据
分别启动五台zk服务器
./server001/bin/zkServer.sh start./server002/bin/zkServer.sh start./server003/bin/zkServer.sh start./server004/bin/zkServer.sh start./server005/bin/zkServer.sh start![zookeeper集群启动][1]
启动成功后,测试节点是否能够正常写入读取(这里提前创建了一个/zk_test节点)
启动zk客户端
./bin/zkCli.sh/zk_test测试写入123:set /zk_test 123 发现可以正常写入与读取![zk写入与读取][2]
2.创建node服务
定义thrift提供的服务,新建thrift文件,定义返回zk数据的服务:zkDataService,服务中有一个方法zkData返回节点数据
namespace php tutorialservice zkDataService { string zkData()}
根据thrift协议生成服务端可客户端的中间代码(生成中间代码我放在windows上完成),
C:Users77388AppDatathrift-0.10.0.exe -r --gen js:node zkData.thrift
此时会在文件夹中生成中间代码,在gen-nodejs文件夹中
![生成node端中间代码][3]
node安装zookeeper模块:cnpm install node-zookeeper-client,编写子进程support.js,自动发现zk节点数据变更
console.log('pid in worker:', process.pid);process.on('message', function(msg) { console.log('3:', msg);});var i=0;var zookeeper = require('node-zookeeper-client');var client = zookeeper.createClient('localhost:2181');var path = '/zk_test';//节点名称 function getData(client, path) { client.getData( path, function (event) { console.log('Got event: %s', event); getData(client, path); }, function (error, data, stat) { if (error) { console.log('Error occurred when getting data: %s.', error); return; } process.send('zookeeper节点数据'+data.toString('utf8'));//通知主进程zk节点数据 } );} client.once('connected', function () { console.log('Connected to ZooKeeper.'); getData(client, path);}); client.connect();process.emit('message', '======');
编写主进程server.js,实现thrift定义的服务,并在主进程中启动子进程
var childprocess = require('child_process');var worker = childprocess.fork('./support.js');console.log('pid in master:', process.pid);var childMessage="";//监听子进程事件worker.on('message', function(msg) { childMessage=msg; console.log('1:', msg);//监听子进程zk数据,并将zk节点数据打印})process.on('message', function(msg) { console.log('2:', msg);})
worker.send('主进程给子进程传递的数据');
//触发事件 messageprocess.emit('message', '------');var thrift = require("thrift");var zkDataService = require("./gen-nodejs/zkDataService");var ttypes = require("./gen-nodejs/tutorial_types");var data = {};var server = thrift.createServer(zkDataService, { zkData: function(result) { result(null, childMessage);//将zk节点数据返回 }});server.listen(9090);
启动nodeJs主进程:node server.js
3.创建php服务,在php服务中也要生成thrift中间件程序,与node端类似,php端调用node主进程server.js的zkData方法,获取zk节点数据
<?phpnamespace tutorialphp;error_reporting(E_ALL);require_once __DIR__.'/lib/Thrift/ClassLoader/ThriftClassLoader.php';require_once __DIR__.'/gen-php/tutorial/zkDataService.php';use ThriftClassLoaderThriftClassLoader;$GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php';$loader = new ThriftClassLoader();$loader->registerNamespace('Thrift', __DIR__ . '/lib');$loader->registerDefinition('shared', $GEN_DIR);$loader->registerDefinition('tutorial', $GEN_DIR);$loader->register();/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */use ThriftProtocolTBinaryProtocol;use ThriftTransportTSocket;use ThriftTransportTHttpClient;use ThriftTransportTBufferedTransport;use ThriftExceptionTException;try { if (array_search('--http', $argv)) { $socket = new THttpClient('localhost', 8080, '/php/PhpServer.php'); } else { $socket = new TSocket('192.168.0.105', 9090); } $transport = new TBufferedTransport($socket, 1024, 1024); $protocol = new TBinaryProtocol($transport); $client = new tutorialzkDataServiceClient($protocol); $transport->open(); $result= $client->zkData(); print "$result";//打印zk节点数据 $transport->close();} catch (TException $tx) { print 'TException: '.$tx->getMessage()."n";}?>
启动php服务,发现正常获取zk数据
修改zookeeper数据,在启动php服务,发现可以自动发现
总结:
自此,php和nodeJS相协作,完成php服务对zk数据的自动发现就完成了。架构的整体思路是node子进程实现zk的自动发现,node主进程维护一个zk节点数据的共享变量,其他服务要想使用zk节点数据时,从node主进程中获取。
以上就是php+nodeJs+thrift协议,实现zookeeper节点数据自动发现的详细内容,更多请关注Gxl网其它相关文章!
内容总结
以上是为您收集整理的php+nodeJs+thrift协议,实现zookeeper节点数据自动发现全部内容,希望文章能够帮你解决php+nodeJs+thrift协议,实现zookeeper节点数据自动发现所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。