摘要:下面一起學(xué)習(xí)下鳥哥的框架。揭開神秘面紗采用客戶端服務(wù)器模式。在服務(wù)器端,進程保持睡眠狀態(tài)直到調(diào)用信息的到達為止。這和我們外網(wǎng)的原理不都一個樣么那么我們一起看看高大上的是怎么在玩。整個傳輸以二進制流的形式傳送。
各位老鐵在點贊、收藏的時候敢不敢報名小弟的直播分享,絕對有干貨,絕對有驚喜!
一次早餐錢的投入,可能是薪資的翻倍,可能是視野的拓展!PHP 進階之路 - 億級 pv 網(wǎng)站架構(gòu)的技術(shù)細(xì)節(jié)與套路
PHP 進階之路 - 億級 pv 網(wǎng)站架構(gòu)實戰(zhàn)之性能壓榨
PHP 進階之路 - 后端多元化之快速切入 Java 開發(fā)
模塊越來越多,業(yè)務(wù)越來越復(fù)雜,RPC 就上場了,在 PHP 的世界里,鳥哥的作品一直備受廣大網(wǎng)友的青睞。下面一起學(xué)習(xí)下鳥哥的 PRC 框架 Yar 。
揭開 Yar 神秘面紗RPC 采用客戶端/服務(wù)器模式。首先,客戶機調(diào)用進程發(fā)送一個有進程參數(shù)的調(diào)用信息到服務(wù)進程,然后等待應(yīng)答信息。在服務(wù)器端,進程保持睡眠狀態(tài)直到調(diào)用信息的到達為止。當(dāng)一個調(diào)用信息到達,服務(wù)器獲得進程參數(shù),計算結(jié)果,發(fā)送答復(fù)信息,然后等待下一個調(diào)用信息,最后,客戶端調(diào)用進程接收答復(fù)信息,獲得進程結(jié)果,然后調(diào)用執(zhí)行繼續(xù)進行。
這和我們外網(wǎng) api 的原理不都一個樣么?那么我們一起看看高大上的 Yar 是怎么在玩。
客戶端代碼,假設(shè)該服務(wù)設(shè)在局域網(wǎng)10.211.55.4上
"http://10.211.55.4/yar/server/RewardScoreService.class.php", ); public static function init($server){ if (array_key_exists($server, self::$rpcConfig)) { $uri = self::$rpcConfig[$server]; return new Yar_Client($uri); } } } $RewardScoreService = RpcClient::init("RewardScoreService"); var_dump($RewardScoreService->support(1, 2));
服務(wù)器端代碼
handle();
訪問結(jié)果如下
uid = 1, feedId = 2Yar 遠(yuǎn)程調(diào)用的實現(xiàn)原理
實際呢,yar client 是通過__call這個魔術(shù)方法來實現(xiàn)遠(yuǎn)程調(diào)用的,在Yar_client類里面并沒有任何方法,當(dāng)我們在調(diào)用一個不存在的方式的時候,就會執(zhí)行__call方法,這個在框架中非常常見。
Yar 協(xié)議分析在 yar 中規(guī)定的傳輸協(xié)議如下圖所示,請求體為82個字節(jié)的yar_header_t和8字節(jié)的打包名稱和請求實體yar_request_t,在yar_header_t里面用body_len記錄8字節(jié)的打包名稱+請求實體的長度;返回體類似,只是實體內(nèi)容的結(jié)構(gòu)體稍微不同,在reval里面才是實際最后客戶端需要的結(jié)果。
整個傳輸以二進制流的形式傳送。
Yar 數(shù)據(jù)傳輸?shù)恼w流程分析在yar_transport.h中,定義了yar_transport_t結(jié)構(gòu)體,先不考慮并行處理的接口,以socket傳輸協(xié)議為例子學(xué)習(xí),代碼簡化一些如下:
typedef struct _yar_transport_interface { void *data; int (*open)(struct _yar_transport_interface *self, char *address, uint len, long options, char **msg TSRMLS_DC); int (*send)(struct _yar_transport_interface *self, struct _yar_request *request, char **msg TSRMLS_DC); struct _yar_response * (*exec)(struct _yar_transport_interface *self, struct _yar_request *request TSRMLS_DC); int (*setopt)(struct _yar_transport_interface *self, long type, void *value, void *addition TSRMLS_DC); int (*calldata)(struct _yar_transport_interface *self, yar_call_data_t *calldata TSRMLS_DC); void (*close)(struct _yar_transport_interface *self TSRMLS_DC); } yar_transport_interface_t; typedef struct _yar_transport { const char *name; struct _yar_transport_interface * (*init)(TSRMLS_D); void (*destroy)(yar_transport_interface_t *self TSRMLS_DC); yar_transport_multi_t *multi; } yar_transport_t;
然后在transports/socket.c中定義了yar_transport_socket
yar_transport_t yar_transport_socket = { "sock", php_yar_socket_init, php_yar_socket_destroy, };
整理了整體的執(zhí)行流程如下圖
Yar 數(shù)據(jù)的打包和解包鳥哥在yar_packager.c中首先定義了一個結(jié)構(gòu)體,初始化的時候會把各個yar_packager_t注冊到**packagers數(shù)組中。
struct _yar_packagers_list { unsigned int size; unsigned int num; yar_packager_t **packagers; } yar_packagers_list;
typedef struct _yar_packager { const char *name; int (*pack) (struct _yar_packager *self, zval *pzval, smart_str *buf, char **msg TSRMLS_DC); zval * (*unpack) (struct _yar_packager *self, char *content, size_t len, char **msg TSRMLS_DC); } yar_packager_t;
然后通過傳入的name和yar_packager_t的name做比較,相同則返回該實例
PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen TSRMLS_DC) /* {{{ */ { int i = 0; for (;iname, name, nlen) == 0) { return yar_packagers_list.packagers[i]; } } return NULL; } /* }}} */
親密接觸完畢。紙上得來終覺淺,絕知此事要躬行。這篇博客只能是輔助大家在看源碼時一起分析,覺不能拋開源碼僅僅看這篇博客。
怎么樣才能對這個內(nèi)容真正的掌握呢,所以我有折騰了一個Java 版本的客戶端,這樣總算有所收獲,這份代碼也和我們平常寫的業(yè)務(wù)邏輯還是有些區(qū)別,二進制的東西居多,整個過程下來對網(wǎng)絡(luò)數(shù)據(jù)的傳輸有了更深刻的理解和學(xué)習(xí)哈。
Github 項目地址: https://github.com/zhoumengka...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/23242.html
摘要:的框架的話語言的話首選的當(dāng)然是鳥哥的,支持并行等等,總之有很多優(yōu)點。首先查看了鳥哥的文章并行的框架,對的基本原理有了一個認(rèn)識,做了一個簡單的請求頁面,具體見鳥哥博客,沒問題,接下來就是對現(xiàn)有項目的改造了。最后感謝鳥哥寫出這么牛掰的東西。 公司新上了個頻道,需要我負(fù)責(zé)的幾個頻道提供接口,因為進度比較趕,就直接寫了web的 http 接口供同事訪問。 后來訪問量越來越大,出現(xiàn)了很多問題,...
摘要:客戶端并行調(diào)用這兩個服務(wù)這里的方法的命令皆以原版為準(zhǔn)則。回調(diào)函數(shù)需要繼承實現(xiàn)里面定義了兩個方法是針對并行調(diào)用發(fā)出之后立即執(zhí)行的任務(wù),而則是每個請求之后返回的結(jié)果。 簡介 Yar 是一個輕量級, 高效的 RPC 框架, 它提供了一種簡單方法來讓 PHP 項目之間可以互相遠(yuǎn)程調(diào)用對方的本地方法. 并且 Yar 也提供了并行調(diào)用的能力. 可以支持同時調(diào)用多個遠(yuǎn)程服務(wù)的方法.Yar 鳥哥博客介...
摘要:需求在了解了前面我們關(guān)于服務(wù)治理出現(xiàn)的必要性之后。我們知道服務(wù)治理是建立在眾多服務(wù)基礎(chǔ)之上的,那么,第一步,打通這些服務(wù)是基礎(chǔ),也就是我們常說的遠(yuǎn)程調(diào)用。上面執(zhí)行遠(yuǎn)程調(diào)用也類似。 需求 在了解了前面我們關(guān)于服務(wù)治理出現(xiàn)的必要性之后。我們知道服務(wù)治理是建立在眾多服務(wù)基礎(chǔ)之上的,那么,第一步,打通這些服務(wù)是基礎(chǔ),也就是我們常說的 RPC 遠(yuǎn)程調(diào)用。要像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程服務(wù)器上的方法...
摘要:棧上各個變量申請的內(nèi)存,返回的地址是這段連續(xù)內(nèi)存的最小的地址。為什么用一個位的十六進制來呢因為個字節(jié),一個字節(jié)有位,每位有兩個狀態(tài),那么就是,也就是。為什么用,純屬演示方便。結(jié)構(gòu)體里的字節(jié)對齊以成員中自身對齊值最大的那個值為標(biāo)準(zhǔn)。 原文:我的個人博客 https://mengkang.net/1046.html初中級 phper 有多久沒給自己充電了呢,安利一波我的直播 PHP 進階之...
摘要:面向服務(wù)面向服務(wù)的基礎(chǔ)面向服務(wù)的三層應(yīng)用層,服務(wù)層,數(shù)據(jù)層應(yīng)用層用于給用戶展示,,,,安卓。在服務(wù)器端,進程保持睡眠狀態(tài)直到調(diào)用信息到達為止。編譯完成,提示我們已經(jīng)在下了。 面向服務(wù) 面向服務(wù)的基礎(chǔ) 面向服務(wù)的三層:應(yīng)用層,服務(wù)層,數(shù)據(jù)層 * 應(yīng)用層:用于給用戶展示,PC,H5,IOS,安卓。 * 服務(wù)層:業(yè)務(wù)邏輯,提供接口(商品,訂單,支付,用戶,物流)。 * 數(shù)據(jù)層:提供數(shù)據(jù)支持(...
閱讀 2092·2023-04-25 20:52
閱讀 2473·2021-09-22 15:22
閱讀 2122·2021-08-09 13:44
閱讀 1766·2019-08-30 13:55
閱讀 2804·2019-08-23 15:42
閱讀 2278·2019-08-23 14:14
閱讀 2871·2019-08-23 13:58
閱讀 3002·2019-08-23 11:49