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服務器掛載第二塊磁盤(阿里云服務器掛載資料盤)
下一篇:給你看看小白博主開發的打賞系統
