主頁 > 後端開發 > 幫助 phper 理解 RPC 是怎么回事兒

幫助 phper 理解 RPC 是怎么回事兒

2020-09-13 12:41:34 後端開發

1. 什么是 rpc

RPC 全稱為 Remote Procedure Call,翻譯過來為 “遠程程序呼叫”,

目前,主流的平臺中都支持各種遠程呼叫技術,以滿足分布式系統架構中不同的系統之間的遠程通信和相互呼叫,遠程呼叫的應用場景極其廣泛,實作的方式也各式各樣,

2. 從通信協議的層面

基于 HTTP 協議的(例如基于文本的 SOAP(XML)、Rest(JSON),基于二進制 Hessian(Binary))

基于 TCP 協議的(通常會借助 Mina、Netty 等高性能網路框架)

RPC (遠程程序呼叫) 是什么

  • 簡單的說,RPC 就是從一臺機器(客戶端)上通過引數傳遞的方式呼叫另一臺機器(服務器)上的一個函式或方法(可以統稱為服務)并得到回傳的結果,
  • RPC 會隱藏底層的通訊細節(不需要直接處理 Socket 通訊或 Http 通訊)
  • RPC 是一個請求回應模型,客戶端發起請求,服務器回傳回應(類似于 Http 的作業方式)
  • RPC 在使用形式上像呼叫本地函式(或方法)一樣去呼叫遠程的函式(或方法),

遠程程序呼叫發展歷程

  • ONC RPC (開放網路計算的遠程程序呼叫),OSF RPC(開放軟體基金會的遠程程序呼叫)
  • CORBA(Common Object Request Broker Architecture 公共物件請求代理體系結構)
  • DCOM(分布式組件物件模型),COM+
  • .NET Remoting
  • XML-RPC,SOAP,Web Service
  • PHPRPC,Hessian,JSON-RPC
  • Microsoft WCF,WebAPI
  • ZeroC Ice,Thrift,GRPC
  • Hprose

早期的 RPC

  • 第一代 RPC(ONC RPC,OSF RPC)不支持物件的傳遞,
  • CORBA 太復雜,各種不同實作不兼容,一般程式員也玩不轉,
  • DCOM,COM+ 逃不出 Windows 的手掌心,
  • RMI 只能在 Java 里面玩,
  • .NET Remoting 只能在 .NET 平臺上玩,

XML-RPC,SOAP,WebService

  • 冗余資料太多,處理速度太慢,
  • RPC 風格的 Web Service 跨語言性不佳,而 Document 風格的 Web Service 又太過難用,
  • Web Service 沒有解決用戶的真正問題,只是把一個問題變成了另一個問題,
  • Web Service 的規范太過復雜,以至于在 .NET 和 Java 平臺以外沒有真正好用的實作,甚至沒有可用的實作,
  • 跨語言跨平臺只是 Web Service 的一個口號,雖然很多人迷信這一點,但事實上它并沒有真正實作,

 

PHPRPC

  • 基于 PHP 內置的序列化格式,在跨語言的型別映射上存在硬傷,
  • 通訊上依賴于 HTTP 協議,沒有其它底層通訊方式的選擇,
  • 內置的加密傳輸既是特點,也是缺點,
  • 雖然比基于 XML 的 RPC 速度快,但還不是足夠快,

Hessian

  • 二進制的資料格式完全不具有可讀性,
  • 官方只提供了兩個半語言的實作(Java,ActionScript 和不怎么完美的 Python 實作),其它語言的第三方實作良莠不齊,
  • 支持的語言不夠多,對 Web 前端的 JavaScript 完全無視,
  • 雖然是動態 RPC,但動態性仍然欠佳,
  • 雖然比基于 XML 的 RPC 速度快,但還不是足夠快,

JSON-RPC

  • JSON 具有文本可讀性,且比 XML 更簡潔,
  • JSON 受 JavaScript 語言子集的限制,可表示的資料型別不夠多,
  • JSON 格式無法表示資料內的自參考,互參考和回圈參考,
  • 某些語言具有多種版本的實作,但在型別影射上沒有統一標準,存在兼容性問題,
  • JSON-RPC 雖然有規范,但是卻沒有統一的實作,在不同語言中的各自實作存在兼容性問題,無法真正互通,

Microsoft WCF,WebAPI

  • 它們是微軟對已有技術的一個 .NET 平臺上的統一封裝,是對 .NET Remoting、WebService 和基于 JSON 、XML 等資料格式的 REST 風格的服務等技術的一個整合,
  • 雖然號稱可以在 .NET 平臺以外來呼叫它的這些服務,但實際上跟在 .NET 平臺內呼叫完全是兩碼事,它沒有提供任何在其他平臺的語言中可以使用的任何工具

ZeroC Ice,Thrift,GRPC

  • 初代 RPC 技術的跨語言面向物件的回歸,
  • 仍然需要通過中間語言來撰寫型別和介面定義,
  • 仍然需要用代碼生成器來將中間語言撰寫的型別和介面定義翻譯成你所使用的編程語言的客戶端和服務器端的占位程式(stub),
  • 你必須要基于生成的服務器代碼來單獨撰寫服務,而不能將已有代碼直接作為服務發布,
  • 你必須要用生成的客戶端代碼來呼叫服務,而沒有其它更靈活的方式,
  • 如果你的中間代碼做了修改,以上所有步驟你都要至少重復一遍,

Hprose

  • 無侵入式設計,不需要單獨定義型別,不需要單獨撰寫服務,已有代碼可以直接發布為服務,
  • 具有豐富的資料型別和完美的跨語言型別映射,支持自參考,互參考和回圈參考資料,
  • 支持眾多傳輸方式,如 HTTP、TCP、Websocket 等,
  • 客戶端具有更靈活的呼叫方式,支持同步呼叫,異步呼叫,動態引數,可變引數,參考引數傳遞,多結果回傳(Golang)等語言特征,Hprose 2.0 甚至支持推送,
  • 具有良好的可擴展性,可以通過過濾器和中間件實作加密、壓縮、快取、代理等各種功能性擴展,
  • 兼容的無差別跨語言呼叫
  • 支持更多的常用語言和平臺
  • 支持瀏覽器端的跨域呼叫
  • 沒有中間語言,無需學習成本
  • 性能卓越,使用簡單

RPC 與 Socket 有什么區別?

兩者都是呼叫遠程的方法,都是 client/server 模式,

RPC(遠程程序呼叫)采用客戶機 / 服務器模式實作兩個行程之間相互通信,socket 是 RPC 經常采用的通信手段之一,RPC 是在 Socket 的基礎上實作的,它比 socket 需要更多的網路和系統資源,除了 Socket,RPC 還有其他的通信方法,比如:http、作業系統自帶的管道等技術來實作對于遠程程式的呼叫,微軟的 Windows 系統中,RPC 就是采用命名管道進行通信,

RPC 與 REST 有什么區別?

通過了解 RPC 后,我們知道是 RPC 是 client/server 模式的,呼叫遠程的方法,REST 也是我們熟悉的一套 API 呼叫協議方法,它也是基于 client/server 模式的,呼叫遠程的方法的,那他倆又有啥區別呢?

REST API 和 RPC 都是在 Server 端 把一個個函式封裝成介面暴露出去,以供 Client 端 呼叫,不過 REST API 是基于 HTTP 協議的,REST 致力于通過 http 協議中的 POST/GET/PUT/DELETE 等方法和一個可讀性強的 URL 來提供一個 http 請求,而 RPC 則可以不基于 HTTP 協議

因此,如果是后端兩種語言互相呼叫,用 RPC 可以獲得更好的性能(省去了 HTTP 報頭等一系列東西),應該也更容易配置,如果是前端通過 AJAX 呼叫后端,那么用 REST API 的形式比較好(因為無論如何也避不開 HTTP 這道坎),

1、HTTP 和 RPC 同一級別,還是被 RPC 包含?

2、Restful 也屬于 RPC 么?

圖掛了

上圖是一個比較完整的關系圖,這時我們發現 HTTP(圖中藍色框)出現了兩次,其中一個是和 RPC 并列的,都是跨應用呼叫方法的解決方案;另一個則是被 RPC 包含的,是 RPC 通信程序的可選協議之一,

因此,第一個問題的答案是都對,看指的是哪一個藍色框,從題主的提問看,既然題主在糾結這兩者,應該是指與 RPC 并列的藍色框,

第二個問題是在問遠程程序呼叫(紅色框)是不是包含了 Restful(黃色框),這種理解的關鍵在于對 RPC 的理解,

RPC 字面理解是遠程程序呼叫,即在一個應用中呼叫另一個應用的方法,那 Restful 是滿足的,通過它可以實作在一個應用中呼叫另一個應用的方法,

但是,上述理解使得 RPC 的定義過于寬泛,RPC 通常特指在一個應用中呼叫另一個應用的介面而實作的遠程呼叫,即紅色框所指的范圍,這樣,RPC 是不包含 Restful 的,

因此,第二個問題的答案是 Restful 不屬于 RPC,除非對 RPC 有著非常規的寬泛理解,

RPC 的英文全稱是 Remote Procedure Call,翻譯為中文叫 “遠程程序呼叫”,其中稍顯晦澀的其實就是 “程序”,程序其實就是方法,所以,可以把 RPC 理解為 “遠程方法呼叫”,

要了解遠程程序呼叫,那先理解程序呼叫,非常簡單,如下圖,就是呼叫一個方法,這太常見了,不多解釋,

而在分布式系統中,因為每個服務的邊界都很小,很有可能呼叫別的服務提供的方法,這就出現了服務 A 呼叫服務 B 中方法的需求,即遠程程序呼叫,

要想讓服務 A 呼叫服務 B 中的方法,最先想到的就是通過 HTTP 請求實作,是的,這是很常見的,例如服務 B 暴露 Restful 介面,然后讓服務 A 呼叫它的介面,基于 Restful 的呼叫方式因為可讀性好(服務 B 暴露出的是 Restful 介面,可讀性當然好)而且 HTTP 請求可以通過各種防火墻,因此非常不錯,

然而,如前面所述,基于 Restful 的遠程程序呼叫有著明顯的缺點,主要是效率低、封裝呼叫復雜,當存在大量的服務間呼叫時,這些缺點變得更為突出,

服務 A 呼叫服務 B 的程序是應用間的內部程序,犧牲可讀性提升效率、易用性是可取的,基于這種思路,RPC 產生了,

通過 hprose 實作 rpc

HPROSE 是 High Performance Remote Object Service Engine 的縮寫,翻譯成中文就是 “高性能遠程物件服務引擎”,

它是一個先進的輕量級的跨語言跨平臺面向物件的高性能遠程動態通訊中間件,它不僅簡單易用,而且功能強大,你只需要稍許的時間去學習,就能用它輕松構建跨語言跨平臺的分布式應用系統了,

Hprose 支持眾多流行的編程語言,例如:

  • AAuto Quicker
  • ActionScript
  • ASP
  • C++
  • Delphi/Free Pascal
  • dotNET(C#, Visual Basic…)
  • Golang
  • Java
  • JavaScript
  • Node.js
  • Objective-C
  • Perl
  • PHP
  • Python
  • Ruby

通過 Hprose,你就可以在這些語言之間方便高效的實作互通了,

基礎實作

在同一個檔案夾下,執行一下操作,分別是拉取組建的命令,創建兩個檔案和執行 php 檔案,

拉取 hprose 組件

composer require hprose/hprose

  

建立 server.php

<?php
require_once "./vendor/autoload.php";
use Hprose\Socket\Server;
function hello($name) {
return "Hello $name!";
}
$server = new Server("tcp://0.0.0.0:1314");
$server->setErrorTypes(E_ALL);
$server->setDebugEnabled();
$server->addFunction('hello');
$server->start();

  

建立 client.php

<?php
require_once "./vendor/autoload.php";
use \Hprose\Future;
use \Hprose\Socket\Client;
$test = new Client("tcp://127.0.0.1:1314");
$test->fullDuplex = true;
Future\co(function() use ($test) {
try {
var_dump((yield $test->hello("yield world1")));
var_dump((yield $test->hello("yield world2")));
var_dump((yield $test->hello("yield world3")));
var_dump((yield $test->hello("yield world4")));
var_dump((yield $test->hello("yield world5")));
var_dump((yield $test->hello("yield world6")));
}
catch (\Exception $e) {
echo ($e);
}
});

  

執行

php server.php
php client.php

  

結果

string(19) "Hello yield world1!"
string(19) "Hello yield world2!"
string(19) "Hello yield world3!"
string(19) "Hello yield world4!"
string(19) "Hello yield world5!"
string(19) "Hello yield world6!"

  

更多學習內容請訪問:

騰訊T3-T4標準精品PHP架構師教程目錄大全,只要你看完保證薪資上升一個臺階(持續更新)

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/24450.html

標籤:PHP

上一篇:Linux服務器掛載第二塊磁盤(阿里云服務器掛載資料盤)

下一篇:給你看看小白博主開發的打賞系統

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more