成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

php+nodeJs+thrift協(xié)議,實(shí)現(xiàn)zookeeper節(jié)點(diǎn)數(shù)據(jù)自動(dòng)發(fā)現(xiàn)

MingjunYang / 2628人閱讀

摘要:可以在主進(jìn)程中拋出一個(gè)子進(jìn)程,子進(jìn)程中實(shí)現(xiàn)的自動(dòng)發(fā)現(xiàn),子進(jìn)程偵察到節(jié)點(diǎn)數(shù)據(jù)變化時(shí),主動(dòng)通知主進(jìn)程。架構(gòu)的整體思路是子進(jìn)程實(shí)現(xiàn)的自動(dòng)發(fā)現(xiàn),主進(jìn)程維護(hù)一個(gè)節(jié)點(diǎn)數(shù)據(jù)的共享變量,其他服務(wù)要想使用節(jié)點(diǎn)數(shù)據(jù)時(shí),從主進(jìn)程中獲取。

php是當(dāng)下最流行的web服務(wù)器端語(yǔ)言,zookeeper是大型分布式協(xié)同工具,本文在這里介紹一種架構(gòu)實(shí)現(xiàn)php服務(wù)器對(duì)于zookeeper數(shù)據(jù)變化的自動(dòng)監(jiān)聽(tīng)

一.問(wèn)題背景
php可以CLI模式模式連接zookeeper(下面簡(jiǎn)稱(chēng)zk),并實(shí)現(xiàn)zk節(jié)點(diǎn)數(shù)據(jù)的自動(dòng)發(fā)現(xiàn),這里不做過(guò)多敘述。但web服務(wù)器中,php只能主動(dòng)連接zk以獲得節(jié)點(diǎn)數(shù)據(jù),做不到zk數(shù)據(jù)的自動(dòng)發(fā)現(xiàn)。其次,php web服務(wù),也難以和php CLI模式下的服務(wù)共享數(shù)據(jù)變量(cli模式下zk數(shù)據(jù)做成共享變量)。這就導(dǎo)致如果并發(fā)量大的話(huà),每一個(gè)http請(qǐng)求php都會(huì)去連接zk,zk集群的壓力會(huì)很大,其次,每一個(gè)請(qǐng)求都會(huì)連接zk,請(qǐng)求結(jié)束又釋放zk連接,zk的連接與釋放過(guò)于頻繁。

二.解決思路
nodeJs多進(jìn)程間可以通信,可以解決php服務(wù)難以實(shí)現(xiàn)共享變量的問(wèn)題。nodeJs可以在主進(jìn)程中拋出一個(gè)子進(jìn)程,子進(jìn)程中實(shí)現(xiàn)zk的自動(dòng)發(fā)現(xiàn),子進(jìn)程偵察到zk節(jié)點(diǎn)數(shù)據(jù)變化時(shí),主動(dòng)通知主進(jìn)程。node主進(jìn)程寫(xiě)一個(gè)服務(wù),像外界提供zk的數(shù)據(jù)。php web服務(wù)需要zk節(jié)點(diǎn)數(shù)據(jù)時(shí),通過(guò)RPC協(xié)議(這里使用thrift協(xié)議),訪(fǎng)問(wèn)本地node主進(jìn)程服務(wù),來(lái)獲取zk節(jié)點(diǎn)數(shù)據(jù)。這樣做有三點(diǎn)好處:1.實(shí)現(xiàn)zk節(jié)點(diǎn)變化的自動(dòng)發(fā)現(xiàn);

     2.php和node通信在同一臺(tái)服務(wù)器上,不走網(wǎng)管,速度快,穩(wěn)定性可靠
     3.thrift協(xié)議直接操作套接字傳輸數(shù)據(jù),比http服務(wù)要快,可以近似看作php調(diào)用自己的方法

三.具體實(shí)現(xiàn)

1.搭建zookeeper服務(wù),這里我搭了一個(gè)5臺(tái)zk服務(wù)的偽集群(zk服務(wù)的搭建這里不做過(guò)多介紹),測(cè)試zk服務(wù)是否能正常寫(xiě)入與讀取節(jié)點(diǎn)數(shù)據(jù)
分別啟動(dòng)五臺(tái)zk服務(wù)器./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集群?jiǎn)?dòng)][1]
啟動(dòng)成功后,測(cè)試節(jié)點(diǎn)是否能夠正常寫(xiě)入讀取(這里提前創(chuàng)建了一個(gè)/zk_test節(jié)點(diǎn))
啟動(dòng)zk客戶(hù)端./bin/zkCli.sh
/zk_test測(cè)試寫(xiě)入123:set /zk_test 123 發(fā)現(xiàn)可以正常寫(xiě)入與讀取
![zk寫(xiě)入與讀取][2]



2.創(chuàng)建node服務(wù)
定義thrift提供的服務(wù),新建thrift文件,定義返回zk數(shù)據(jù)的服務(wù):zkDataService,服務(wù)中有一個(gè)方法zkData返回節(jié)點(diǎn)數(shù)據(jù)
namespace php tutorial
service zkDataService {
     string zkData()
}
根據(jù)thrift協(xié)議生成服務(wù)端可客戶(hù)端的中間代碼(生成中間代碼我放在windows上完成),C:Users77388AppData	hrift-0.10.0.exe -r --gen js:node zkData.thrift
此時(shí)會(huì)在文件夾中生成中間代碼,在gen-nodejs文件夾中
![生成node端中間代碼][3]
node安裝zookeeper模塊:cnpm install node-zookeeper-client,編寫(xiě)子進(jìn)程support.js,自動(dòng)發(fā)現(xiàn)zk節(jié)點(diǎn)數(shù)據(jù)變更
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";//節(jié)點(diǎn)名稱(chēng)
 


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節(jié)點(diǎn)數(shù)據(jù)"+data.toString("utf8"));//通知主進(jìn)程zk節(jié)點(diǎn)數(shù)據(jù)
        }
    );
}


 
client.once("connected", function () {
    console.log("Connected to ZooKeeper.");
    getData(client, path);
});
 
client.connect();

process.emit("message", "======");

編寫(xiě)主進(jìn)程server.js,實(shí)現(xiàn)thrift定義的服務(wù),并在主進(jìn)程中啟動(dòng)子進(jìn)程

var childprocess = require("child_process");
var worker = childprocess.fork("./support.js");

console.log("pid in master:", process.pid);
var childMessage="";
//監(jiān)聽(tīng)子進(jìn)程事件
worker.on("message", function(msg) {
  childMessage=msg;
  console.log("1:", msg);//監(jiān)聽(tīng)子進(jìn)程zk數(shù)據(jù),并將zk節(jié)點(diǎn)數(shù)據(jù)打印
})
process.on("message", function(msg) {
  console.log("2:", msg);
})

worker.send("主進(jìn)程給子進(jìn)程傳遞的數(shù)據(jù)");

//觸發(fā)事件 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節(jié)點(diǎn)數(shù)據(jù)返回
  }
});

server.listen(9090);

啟動(dòng)nodeJs主進(jìn)程:node server.js

3.創(chuàng)建php服務(wù),在php服務(wù)中也要生成thrift中間件程序,與node端類(lèi)似,php端調(diào)用node主進(jìn)程server.js的zkData方法,獲取zk節(jié)點(diǎn)數(shù)據(jù)

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節(jié)點(diǎn)數(shù)據(jù)

  $transport->close();

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

?>

啟動(dòng)php服務(wù),發(fā)現(xiàn)正常獲取zk數(shù)據(jù)

修改zookeeper數(shù)據(jù),在啟動(dòng)php服務(wù),發(fā)現(xiàn)可以自動(dòng)發(fā)現(xiàn)

總結(jié):自此,php和nodeJS相協(xié)作,完成php服務(wù)對(duì)zk數(shù)據(jù)的自動(dòng)發(fā)現(xiàn)就完成了。架構(gòu)的整體思路是node子進(jìn)程實(shí)現(xiàn)zk的自動(dòng)發(fā)現(xiàn),node主進(jìn)程維護(hù)一個(gè)zk節(jié)點(diǎn)數(shù)據(jù)的共享變量,其他服務(wù)要想使用zk節(jié)點(diǎn)數(shù)據(jù)時(shí),從node主進(jìn)程中獲取。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/25768.html

相關(guān)文章

  • PowerDotNet平臺(tái)化軟件架構(gòu)設(shè)計(jì)與實(shí)現(xiàn)系列(04):服務(wù)治理平臺(tái)

    摘要:的服務(wù)治理平臺(tái)發(fā)源于早期的個(gè)人項(xiàng)目??蛻?hù)端發(fā)現(xiàn)模式要求客戶(hù)端負(fù)責(zé)查詢(xún)注冊(cè)中心,獲取服務(wù)提供者的列表信息,使用負(fù)載均衡算法選擇一個(gè)合適的服務(wù)提供者,發(fā)起接口調(diào)用請(qǐng)求。系統(tǒng)和系統(tǒng)之間,少不了數(shù)據(jù)的互聯(lián)互通。隨著微服務(wù)的流行,一個(gè)系統(tǒng)內(nèi)的不同應(yīng)用進(jìn)行互聯(lián)互通也是常態(tài)。 PowerDotNet的服務(wù)治理平臺(tái)發(fā)源于早期的個(gè)人項(xiàng)目Power.Apix。這個(gè)項(xiàng)目借鑒了工作過(guò)的公司的服務(wù)治理方案,站在...

    reclay 評(píng)論0 收藏0
  • RPC框架原理及從零實(shí)現(xiàn)系列博客(一):思路篇

    摘要:等之所以支持跨語(yǔ)言,是因?yàn)樗麄冏约憾x了一套結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)格式,如的,用于編解碼對(duì)象,作為各個(gè)語(yǔ)言通信的中間協(xié)議。 前段時(shí)間覺(jué)得自己一直用別人的框架,站在巨人的肩膀上,也該自己造造輪子了 一時(shí)興起 就著手寫(xiě)起了RPC框架 這里寫(xiě)了系列博客拿給大家分享下 這篇是開(kāi)篇的思路篇 項(xiàng)目最終的代碼放在了我的github上https://github.com/wephone/Me... 歡迎sta...

    tracy 評(píng)論0 收藏0
  • Dubbo 一篇文章就夠了:從入門(mén)到實(shí)戰(zhàn)

    摘要:?jiǎn)?dòng)容器,加載,運(yùn)行服務(wù)提供者。服務(wù)提供者在啟動(dòng)時(shí),在注冊(cè)中心發(fā)布注冊(cè)自己提供的服務(wù)。注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者。 一 為什么需要 dubbo 很多時(shí)候,其實(shí)我們使用這個(gè)技術(shù)的時(shí)候,可能都是因?yàn)轫?xiàng)目需要,所以,我們就用了,但是,至于為什么我們需要用到這個(gè)技術(shù),可能自身并不是很了解的,但是,其實(shí)了解技術(shù)的來(lái)由及背景知識(shí),對(duì)...

    tomener 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<