资讯专栏INFORMATION COLUMN

php+nodeJs+thrift协议,实现zookeeper节点数据自动发现

MingjunYang / 2566人阅读

摘要:可以在主进程中抛出一个子进程,子进程中实现的自动发现,子进程侦察到节点数据变化时,主动通知主进程。架构的整体思路是子进程实现的自动发现,主进程维护一个节点数据的共享变量,其他服务要想使用节点数据时,从主进程中获取。

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 tutorial
service zkDataService {
     string zkData()
}
根据thrift协议生成服务端可客户端的中间代码(生成中间代码我放在windows上完成),C:Users77388AppData	hrift-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("主进程给子进程传递的数据");

//触发事件 message
process.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节点数据

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 	utorialzkDataServiceClient($protocol);

  $transport->open();

  $result= $client->zkData();
  print "$result";//打印zk节点数据

  $transport->close();

} catch (TException $tx) {
  print "TException: ".$tx->getMessage()."
";
}

?>

启动php服务,发现正常获取zk数据

修改zookeeper数据,在启动php服务,发现可以自动发现

总结:自此,php和nodeJS相协作,完成php服务对zk数据的自动发现就完成了。架构的整体思路是node子进程实现zk的自动发现,node主进程维护一个zk节点数据的共享变量,其他服务要想使用zk节点数据时,从node主进程中获取。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25768.html

相关文章

  • PowerDotNet平台化软件架构设计与实现系列(04):服务治理平台

    摘要:的服务治理平台发源于早期的个人项目。客户端发现模式要求客户端负责查询注册中心,获取服务提供者的列表信息,使用负载均衡算法选择一个合适的服务提供者,发起接口调用请求。系统和系统之间,少不了数据的互联互通。随着微服务的流行,一个系统内的不同应用进行互联互通也是常态。 PowerDotNet的服务治理平台发源于早期的个人项目Power.Apix。这个项目借鉴了工作过的公司的服务治理方案,站在...

    reclay 评论0 收藏0
  • RPC框架原理及从零实现系列博客(一):思路篇

    摘要:等之所以支持跨语言,是因为他们自己定义了一套结构化数据存储格式,如的,用于编解码对象,作为各个语言通信的中间协议。 前段时间觉得自己一直用别人的框架,站在巨人的肩膀上,也该自己造造轮子了 一时兴起 就着手写起了RPC框架 这里写了系列博客拿给大家分享下 这篇是开篇的思路篇 项目最终的代码放在了我的github上https://github.com/wephone/Me... 欢迎sta...

    tracy 评论0 收藏0
  • Dubbo 一篇文章就够了:从入门到实战

    摘要:启动容器,加载,运行服务提供者。服务提供者在启动时,在注册中心发布注册自己提供的服务。注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。 一 为什么需要 dubbo 很多时候,其实我们使用这个技术的时候,可能都是因为项目需要,所以,我们就用了,但是,至于为什么我们需要用到这个技术,可能自身并不是很了解的,但是,其实了解技术的来由及背景知识,对...

    tomener 评论0 收藏0

发表评论

0条评论

MingjunYang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<