成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

關于php使用thrift做服務端開發的那些事

php使用thrift做服務端開發

thrift采用接口描述語言定義和創建服務,用二進制格式傳輸數據,體積更小、效率更高,對于高并發、數據量大和多語言的環境有更好的支持。

Apache Thrift是啥?

Apache Thrift是FaceBook開發的一套可擴展的、跨語言的服務調用框架。簡單的說就是先定義一個配置文件,不同的語言可以利用thrift基于這個配置文件生成各自語言的服務端,不管客戶端用什么語言,都可以調用,也就是說基于thrift協議用java可以調用php的服務。目前支持C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi等語言之間相互調用。

相對于傳統的xml和json等數據傳輸方式來說,thrift采用接口描述語言定義和創建服務,用二進制格式傳輸數據,體積更小、效率更高,對于高并發、數據量大和多語言的環境有更好的支持。

thrift安裝環境要求

  • g++ 4.2

  • boost 1.53.0

  • lex and yacc(基于flex和bison)

如果沒安裝lex和yacc的話要先安裝,否則會make失敗,提示lex和yacc command not found錯誤(一般的機器貌似都沒安,Ubuntu用apt-get install flex bision即可)。

安裝thrift

下載最新版thrift:

wget http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.3/thrift-0.9.3.tar.gz tar xvf thrift-0.9.3.tar.gz cd thrift-0.9.3

2.創建configure文件

// 創建./configure文件 ./bootstrap.sh // 配置并安裝 ./configure make // 檢測是否有問題,如果機子沒有安裝python和java等可能會報錯,不過本文主要講php,安了php環境就行 make check make install

編譯選項

  • 使用./configure –help可以查看選項

  • 如果想禁用某個語言,可以用./configure –without-java

thrift for php安裝環境要求

  • php版本>5.0,因為TBinaryProtocol協議用到了pack()和unpack()函數來序列化數據

  • 需要安裝APC擴展,因為TSocketPool這個類用到了apc_fetch()和apc_store()函數進行apc緩存操作。

php使用thrift的時候,除了要將thrift/lib/php/lib里的基礎文件copy到項目目錄下,還需要將根據配置文件生成的php文件也copy到packages文件夾下,并引入到項目中,這個后續會詳細講。

類庫說明

數據傳輸格式(protocol)

定義的了傳輸內容,對Thrift Type的打包解包,包括:

  • TBinaryProtocol,二進制格式,TBinaryProtocolAccelerated則是依賴于thrift_protocol擴展的快速打包解包。

  • TCompactProtocol,壓縮格式

  • TJSONProtocol,JSON格式

  • TMultiplexedProtocol,利用前三種數據格式與支持多路復用協議的服務端(同時提供多個服務,TMultiplexedProcessor)交互

數據傳輸方式(transport)

定義了如何發送(write)和接收(read)數據,包括:

  • TBufferedTransport,緩存傳輸,寫入數據并不立即開始傳輸,直到刷新緩存。

  • TSocket,使用socket傳輸

  • TFramedTransport,采用分塊方式進行傳輸,具體傳輸實現依賴其他傳輸方式,比如TSocket

  • TCurlClient,使用curl與服務端交互

  • THttpClient,采用stream方式與HTTP服務端交互

  • TMemoryBuffer,使用內存方式交換數據

  • TPhpStream,使用PHP標準輸入輸出流進行傳輸

  • TNullTransport,關閉數據傳輸

  • TSocketPool在TSocket基礎支持多個服務端管理(需要APC支持),自動剔除無效的服務器

開發流程

1、定義IDL(Interface description language)接口描述文件,后綴.thrift

IDL規范:http://thrift.apache.org/docs/idl

thrift types:http://thrift.apache.org/docs/types

2、服務端代碼開發

3、客戶端編寫接入代碼

IDL:
1.tutorial.thrift

include "shared.thrift" namespace php tutorial typedef i32 MyInteger const i32 INT32CONSTANT = 9853 const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} enum Operation {   ADD = 1,   SUBTRACT = 2,   MULTIPLY = 3,   DIVIDE = 4 } struct Work {   1: i32 num1 = 0,   2: i32 num2,   3: Operation op,   4: optional string comment, } exception InvalidOperation {   1: i32 whatOp,   2: string why } service Calculator extends shared.SharedService {    void ping(),    i32 add(1:i32 num1, 2:i32 num2),    i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),    oneway void zip() }

2.shared.thrift

namespace php shared struct SharedStruct {   1: i32 key   2: string value } service SharedService {   SharedStruct getStruct(1: i32 key) }

php服務端

<?php namespace tutorialphp; ini_set('display_errors',1); error_reporting(E_ALL); // 引入類自動加載文件 require_once __DIR__.'/../../lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; // 載入自動加載類 use ThriftClassLoaderThriftClassLoader; // 定義根據.thrift文件生成的php文件 $GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php'; // 注冊thrift服務 $loader = new ThriftClassLoader(); $loader->registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib'); $loader->registerDefinition('shared', $GEN_DIR); $loader->registerDefinition('tutorial', $GEN_DIR); $loader->register(); if (php_sapi_name() == 'cli') {   ini_set("display_errors", "stderr"); } use ThriftProtocolTBinaryProtocol; // 二進制格式打包解包 use ThriftTransportTPhpStream; // php流輸入輸出 use ThriftTransportTBufferedTransport; // 使用緩存 // 開始服務端邏輯 class CalculatorHandler implements tutorialCalculatorIf {   protected $log = array();   public function ping() {     error_log("ping()");   }   // 相加   public function add($num1, $num2) {     error_log("add({$num1}, {$num2})");     return $num1 + $num2;   }   // 枚舉計算類型   public function calculate($logid, tutorialWork $w) {     error_log("calculate({$logid}, {{$w->op}, {$w->num1}, {$w->num2}})");     switch ($w->op) {       case tutorialOperation::ADD:         $val = $w->num1 + $w->num2;         break;       case tutorialOperation::SUBTRACT:         $val = $w->num1 - $w->num2;         break;       case tutorialOperation::MULTIPLY:         $val = $w->num1 * $w->num2;         break;       case tutorialOperation::DIVIDE:         if ($w->num2 == 0) {           $io = new tutorialInvalidOperation();           $io->whatOp = $w->op;           $io->why = "Cannot divide by 0";           throw $io;         }         $val = $w->num1 / $w->num2;         break;       default:         $io = new tutorialInvalidOperation();         $io->whatOp = $w->op;         $io->why = "Invalid Operation";         throw $io;     }     $log = new sharedSharedStruct();     $log->key = $logid;     $log->value = (string)$val;     $this->log[$logid] = $log;     return $val;   }   public function getStruct($key) {     error_log("getStruct({$key})");     // This actually doesn't work because the PHP interpreter is     // restarted for every request.     //return $this->log[$key];     return new sharedSharedStruct(array("key" => $key, "value" => "PHP is stateless!"));   }   public function zip() {     error_log("zip()");   } }; header('Content-Type', 'application/x-thrift'); if (php_sapi_name() == 'cli') {   echo "rn"; } $handler = new CalculatorHandler(); $processor = new tutorialCalculatorProcessor($handler); // 客戶端和服務端在同一個輸入輸出流上 //1) cli 方式:php Client.php | php Server.php  //2) cgi 方式:利用Apache或nginx監聽http請求,調用php-fpm處理,將請求轉換為PHP標準輸入輸出流 $transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W)); $protocol = new TBinaryProtocol($transport, true, true); $transport->open(); $processor->process($protocol, $protocol); $transport->close(); //作為cli方式運行,非阻塞方式監聽,基于libevent實現,非官方實現 //$transportFactory = new TBufferedTransportFactory(); //$protocolFactory = new TBinaryProtocolFactory(true, true); //$transport = new TNonblockingServerSocket('localhost', 9090); //$server = new TNonblockingServer($processor, $transport, $transportFactory, $transportFactory, $protocolFactory, $protocolFactory); //$server->serve(); //作為cli方式運行,監聽端口,官方實現 //$transportFactory = new TBufferedTransportFactory(); //$protocolFactory = new TBinaryProtocolFactory(true, true); //$transport = new TServerSocket('localhost', 9090); //$server = new TSimpleServer($processor, $transport, $transportFactory, $transportFactory, $protocolFactory, $protocolFactory); //$server->serve();

php客戶端

<?php namespace tutorialphp; error_reporting(E_ALL); require_once __DIR__.'/../../lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; use ThriftClassLoaderThriftClassLoader; $GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php'; $loader = new ThriftClassLoader(); $loader->registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib'); $loader->registerDefinition('shared', $GEN_DIR); $loader->registerDefinition('tutorial', $GEN_DIR); $loader->register(); use ThriftProtocolTBinaryProtocol; use ThriftTransportTSocket; use ThriftTransportTHttpClient; use ThriftTransportTBufferedTransport; use ThriftExceptionTException; // 以上配置跟服務端類似 try {   if (array_search('--http', $argv)) {   // 使用http方式連接     $socket = new THttpClient('localhost', 8080, '/php/PhpServer.php');   } else {     // 使用socket連接     $socket = new TSocket('localhost', 9090);   }   $transport = new TBufferedTransport($socket, 1024, 1024);   $protocol = new TBinaryProtocol($transport);   $client = new tutorialCalculatorClient($protocol);   $transport->open();   $client->ping();   print "ping()n";   $sum = $client->add(1,1);   print "1+1=$sumn";   // 調試異常情況   $work = new tutorialWork();   $work->op = tutorialOperation::DIVIDE;   $work->num1 = 1;   $work->num2 = 0;   try {     $client->calculate(1, $work);     print "Whoa! We can divide by zero?n";   } catch (tutorialInvalidOperation $io) {     print "InvalidOperation: $io->whyn";   }   $work->op = tutorialOperation::SUBTRACT;   $work->num1 = 15;   $work->num2 = 10;   $diff = $client->calculate(1, $work);   print "15-10=$diffn";   $log = $client->getStruct(1);   print "Log: $log->valuen";   $transport->close(); } catch (TException $tx) {   print 'TException: '.$tx->getMessage()."n"; }

輸出:

// php client.php --http ping() 1+1=2 InvalidOperation: Cannot divide by 0 15-10=5 Log: PHP is stateless!

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
日日玩日日摸日日上| 特级小箩利无码毛片| 日产乱码一二三区别免费影视| 日本护士毛茸茸XX| 色欲av夜夜嗨av性色av| 同性男男黄网站在线观看国外| 无码中文亚洲AV影音先锋无码| 亚洲AV色一区二区三区蜜桃| 亚洲精品无码成人片| 英语老师没戴套让我C了一节课| 中文字幕日本乱码仑区在线| YY111111少妇影院免费| 丁香狠狠色婷婷久久综合| 国产精品视频第一区二区三区| 韩国免费A级毛片| 久久久久亚洲AV成人网人人| 欧美顶级METART裸体全部自慰| 日本伊人精品一区二区三区| 西西人体44RT NET毛最多| 亚洲日本一线产区和二线产| 18一20亚洲GAY无套| 差差漫画在线观看登录页面弹窗| 国产精品成人99久久久久 | 一二三四在线观看免费高清视频| 97碰碰碰人妻无码视频| 各种少妇正面着BBW撒尿视频| 国农村精品国产自线拍| 免费无码AV片在线观看播放| 色偷偷色噜噜狠狠网站年轻人| 亚洲AV无码久久精品香娇| 游泳教练在水里含我奶小说| 成人国内精品久久久久影院VR| 国产亚洲精品视觉盛宴| 毛片TV网站无套内射TV网站| 日韩一区无码视频| 亚洲AV无码一区二区二三区下载 | 久久久久无码精品国产H动漫| 欧美日韩在线视频一区二区| 无码专区狠狠躁躁天天躁| 永久免费无码AV在线网站| 荡女小姿的YIN乱生活| 精品国产你懂的在线观看| 欧美成人片一区二区三区| 无码H肉动漫在线观看| 夜夜躁狠狠躁日日躁2022| 厨房掀起裙子从后面进去视频| 娇妻被朋友征服中文字幕| 欧亚一二精品在免费看| 亚洲AV无码AV制服另类专区| 92成人午夜福利一区二区| 国产精品无码无片在线观看| 免费乱理伦片在线观看八戒| 无码国产精品一区二区免费式影视| 尤物193在线人妻精品免费| 国产AV激情久久无码天堂| 久久精品国产99精品最新| 日产无人区一线二线三线小 | 久久久久久国产精品美女| 日本丰满护士爆乳XXⅩ| 亚洲熟妇无码V在线观看| 成人午夜高潮刺激免费视频| 久久国产情侣露脸精品| 上司侵犯部下的人妻| 一区二区三区国产精华护肤品| 非洲人与性动交CCOO| 鲁大师在线观看视频在线播放| 天天躁日日躁狠狠躁欧美老妇小说| 在线无码VA中文字幕无码| 国产色母和进口色母区别| 欧美性爱AAAAA| 亚洲欧美综合精品AⅤ一区二区| 粗大黑人巨茎大战欧美成人免费看| 久久久久无码精品国产AV蜜桃1| 天天躁日日躁狠狠躁日日躁| 99热这里有精品| 久久精品A一国产成人免费网站 | 亚洲精品无码久久久久AV麻豆| 成午夜福利人试看120秒| 乱熟女高潮一区二区| 亚洲AV无码一区二区一二区| 成人无码H动漫在线播放| 裸睡时一自慰不小心就滑进去啦| 午夜毛片精彩毛片| 被青梅竹马的学弟给锁定了林擎霄| 久久久久久精品免费免费英国| 无人区乱码一线忘忧草| 才摸两下小奶头就受不了了| 免费一对一真人视频| 亚洲精品乱码日本按摩久久久久| 国产V精品成人免费视频| 欧美日韩精品视频一区二区| 夜夜爽夜夜叫夜夜高潮漏水| 国精产品一区一区三区M| 少妇性SEXBBWZⅩX| おやすみせくよ晚安免费影院| 联系附近成熟妇女| 亚洲精品无码日韩国产不卡AV| 国产成人综合久久精品推最新 | 八戒八戒神马影院在线观看1 | √最新版天堂资源网在线下载| 精品丝袜人妻久久久久久| 无人区码二码三码四码区别| 岛国无码AⅤ片在线观看| 欧美午夜成人精品| 中文字幕一区二区三区乱码| 久久AV无码精品人妻糸列| 亚洲AV无码成人网站久久精品大 | 久久久久久精品人妻免费网站| 亚洲AV成人无码精品区| 国产丰滿老熟女多毛hD| 色噜噜人体337P人体| 宝贝腿抬高点让我爽一点麻豆| 女人不怕粗短就怕蘑菇头什么意 | 麻豆精品传媒卡一卡二老狼| 亚洲日韩在线A视频在线观看| 国色天香卡一卡二乱码| 无人区一码卡二卡三乱码| 国产CHINASEX对白VID| 三级韩国2017在线观看| 成人国产亚洲精品A区天堂| 秋霞午夜成人久久电影网| 99亚洲国产精品精华液| 女人张开腿让男桶喷水高潮| 中字幕一区二区三区乱码| 老师办公室被吃奶好爽在线观看| 亚洲熟女AV综合网五月| 精品久久久中文字幕人妻 | 69风韵老熟女口爆吞精| 免费A级毛片无码A∨中文字幕| 制服 丝袜 有码 无码 中文| 老师黑色双开真丝旗袍恩施MBA| 亚洲最大的成人网站| 久久精品国产男包| 野花在线高清视频| 久久天天婷婷五月俺也去| 又大又大粗又长又硬又爽| 噜噜狠狠色综合久色AⅤ五区| 长腿校花无力呻吟娇喘| 蜜芽亚洲日韩欧美国产高清ΑV| 中文字幕一区二区三区久久网站| 年轻的小婊孑4中文字幕电影| 98精产国品一二三产区区| 欧美一区二区三区红桃小说| 不知火舞和三个小男孩| 日韩欧美人妻系列中文字幕一区二区三区| 成人欧美一区二区三区1314| 色欲色AV免费观看| 国产精品成人网站| 亚洲av成人在线| 精品一区二区三区免费视频| 野花高清在线观看免费官网| 门徒电影高清完整版在线观看| 99久久人妻精品免费一区| 日本高清二区视频久二区| 公交车舒婷1一20全文| 无码日韩精品一区二区人妻| 国外AV无码精品国产精品| 亚洲免费成人av| 蜜臀AV无码一区二区三区| WWWらだ天堂中文在线| 色又黄又爽18禁免费网站现观看| 国产精品麻豆成人AV电影| 亚洲AV综合色区无码另类小说| 久久久久亚洲AV成人片| BGMBGMBGM胖老太太XX| 色狠狠久久AV五月综合| 国产清纯美女爆白浆视频| 亚洲人妻精品一区| 男女啪啪免费观看网站| 成人午夜精品无码区| 性一交一乱一伦一色一情孩交| 精品亚洲国产成人小电影 | 男男H黄动漫啪啪无遮挡网站| 宝宝好大我都握不住了视频| 五十路○の豊満な肉体| 久久精品人妻一区二区三区一 | 秋霞A级毛片在线看| 国产成人精品2021| 亚洲精品AV中文字幕在线| 美女裸体无遮挡永久免费观看网站 | 八戒八戒神马影院在线观看 | 国产精品秘 入口A级熟女| 亚洲鲁丝片AV无码多人| 欧美成人性生活视频| 国产成人婷婷丁香在线| 亚洲日韩精品无码AV一区二区三| 欧美丰满熟妇人妻兽交视频| 国产JJIZZ女人多水| 亚洲日韩V无码中文字幕| 欧亚成年男女深夜百度网盘| 国产偷国产偷亚洲高清日韩| 中国农村真卖BBWBBW| 色综合天天综合网国产成人网| 精品国产乱子伦一区二区三区| 80岁老熟妇乱子伦牲交| 天天看片在线完整版| 久久久久无码精品国产AV蜜桃| 成人国成人国产SUV| 亚洲蜜桃无码视頻精品网| 人妻丰满熟妇av无码区免费蜜臀|