搜尋
首頁後端開發php教程php+nodeJs+thrift協議,實作zookeeper節點資料自動發現

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:\Users\77388\AppData\thrift-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

php+nodeJs+thrift協議,實作zookeeper節點資料自動發現

3.创建php服务,在php服务中也要生成thrift中间件程序,与node端类似,php端调用node主进程server.js的zkData方法,获取zk节点数据

<?php
namespace tutorial\php;
error_reporting(E_ALL);
require_once __DIR__.&#39;/lib/Thrift/ClassLoader/ThriftClassLoader.php&#39;;
require_once __DIR__.&#39;/gen-php/tutorial/zkDataService.php&#39;;
use Thrift\ClassLoader\ThriftClassLoader;
$GEN_DIR = realpath(dirname(__FILE__).&#39;/..&#39;).&#39;/gen-php&#39;;
$loader = new ThriftClassLoader();
$loader->registerNamespace(&#39;Thrift&#39;, __DIR__ . &#39;/lib&#39;);
$loader->registerDefinition(&#39;shared&#39;, $GEN_DIR);
$loader->registerDefinition(&#39;tutorial&#39;, $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 Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TSocket;
use Thrift\Transport\THttpClient;
use Thrift\Transport\TBufferedTransport;
use Thrift\Exception\TException;
try {
  if (array_search(&#39;--http&#39;, $argv)) {
    $socket = new THttpClient(&#39;localhost&#39;, 8080, &#39;/php/PhpServer.php&#39;);
  } else {
    $socket = new TSocket(&#39;192.168.0.105&#39;, 9090);
  }
  $transport = new TBufferedTransport($socket, 1024, 1024);
  $protocol = new TBinaryProtocol($transport);
  $client = new \tutorial\zkDataServiceClient($protocol);
  $transport->open();
  $result= $client->zkData();
  print "$result";//打印zk节点数据
  $transport->close();
} catch (TException $tx) {
  print &#39;TException: &#39;.$tx->getMessage()."\n";
}
?>

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

php+nodeJs+thrift協議,實作zookeeper節點資料自動發現

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

php+nodeJs+thrift協議,實作zookeeper節點資料自動發現

总结:

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

以上是php+nodeJs+thrift協議,實作zookeeper節點資料自動發現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault。如有侵權,請聯絡admin@php.cn刪除
哪些常見問題會導致PHP會話失敗?哪些常見問題會導致PHP會話失敗?Apr 25, 2025 am 12:16 AM

PHPSession失效的原因包括配置錯誤、Cookie問題和Session過期。 1.配置錯誤:檢查並設置正確的session.save_path。 2.Cookie問題:確保Cookie設置正確。 3.Session過期:調整session.gc_maxlifetime值以延長會話時間。

您如何在PHP中調試與會話相關的問題?您如何在PHP中調試與會話相關的問題?Apr 25, 2025 am 12:12 AM

在PHP中調試會話問題的方法包括:1.檢查會話是否正確啟動;2.驗證會話ID的傳遞;3.檢查會話數據的存儲和讀取;4.查看服務器配置。通過輸出會話ID和數據、查看會話文件內容等方法,可以有效診斷和解決會話相關的問題。

如果session_start()被多次調用會發生什麼?如果session_start()被多次調用會發生什麼?Apr 25, 2025 am 12:06 AM

多次調用session_start()會導致警告信息和可能的數據覆蓋。 1)PHP會發出警告,提示session已啟動。 2)可能導致session數據意外覆蓋。 3)使用session_status()檢查session狀態,避免重複調用。

您如何在PHP中配置會話壽命?您如何在PHP中配置會話壽命?Apr 25, 2025 am 12:05 AM

在PHP中配置會話生命週期可以通過設置session.gc_maxlifetime和session.cookie_lifetime來實現。 1)session.gc_maxlifetime控制服務器端會話數據的存活時間,2)session.cookie_lifetime控制客戶端cookie的生命週期,設置為0時cookie在瀏覽器關閉時過期。

使用數據庫存儲會話的優點是什麼?使用數據庫存儲會話的優點是什麼?Apr 24, 2025 am 12:16 AM

使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

您如何在PHP中實現自定義會話處理?您如何在PHP中實現自定義會話處理?Apr 24, 2025 am 12:16 AM

在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

什麼是會話ID?什麼是會話ID?Apr 24, 2025 am 12:13 AM

SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

您如何在無狀態環境(例如API)中處理會議?您如何在無狀態環境(例如API)中處理會議?Apr 24, 2025 am 12:12 AM

在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。