日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RPC简介及框架选择

發(fā)布時間:2023/12/10 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RPC简介及框架选择 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

簡單介紹RPC協(xié)議及常見框架,對比傳統(tǒng)restful api和RPC方式的優(yōu)缺點。常見RPC框架,gRPC及序列化方式Protobuf等
HTTP協(xié)議
http協(xié)議是基于tcp協(xié)議的,tcp協(xié)議是流式協(xié)議,包頭部分可以通過多出的\r\n來分界,包體部分如何分界呢?這是協(xié)議本身要解決的問題。目前一般有兩種方式,第一種方式就是在包頭中有個content-Length字段,這個字段的值的大小標(biāo)識了POST數(shù)據(jù)的長度,服務(wù)器收到一個數(shù)據(jù)包后,先從包頭解析出這個字段的值,再根據(jù)這個值去讀取相應(yīng)長度的作為http協(xié)議的包體數(shù)據(jù)。
瀏覽器connect 80端口
RESTful API (http+json)
網(wǎng)站即軟件,而且是一種新型的軟件,這種"互聯(lián)網(wǎng)軟件"采用客戶端/服務(wù)器模式,建立在分布式體系上,通過互聯(lián)網(wǎng)通信,具有高延時(high latency)、高并發(fā)等特點。
  它首次出現(xiàn)在 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規(guī)范的主要編寫者之一。Representational State Transfer,翻譯是”表現(xiàn)層狀態(tài)轉(zhuǎn)化”,通俗來講就是:資源在網(wǎng)絡(luò)中以某種表現(xiàn)形式進(jìn)行狀態(tài)轉(zhuǎn)移。
總結(jié)一下什么是RESTful架構(gòu):
  (1)每一個URI代表一種資源;
  (2)客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層,比如用JSON,XML,JPEG等;
  (3)客戶端通過四個HTTP動詞,對服務(wù)器端資源進(jìn)行操作,實現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

URL定位資源,用HTTP動詞(GET,POST,DELETE,DETC)描述操作。
用HTTP協(xié)議里的動詞來實現(xiàn)資源的添加,修改,刪除等操作。即通過HTTP動詞來實現(xiàn)資源的狀態(tài)扭轉(zhuǎn):
  GET 用來獲取資源,
  POST 用來新建資源(也可以用于更新資源),
  PUT 用來更新資源,
  DELETE 用來刪除資源。
  RPC
進(jìn)程間通信(IPC,Inter-Process Communication),指至少兩個進(jìn)程或線程間傳送數(shù)據(jù)或信號的一些技術(shù)或方法。進(jìn)程是計算機(jī)系統(tǒng)分配資源的最小單位。每個進(jìn)程都有自己的一部分獨立的系統(tǒng)資源,彼此是隔離的。為了能使不同的進(jìn)程互相訪問資源并進(jìn)行協(xié)調(diào)工作,才有了進(jìn)程間通信。這些進(jìn)程可以運(yùn)行在同一計算機(jī)上或網(wǎng)絡(luò)連接的不同計算機(jī)上。 進(jìn)程間通信技術(shù)包括消息傳遞、同步、共享內(nèi)存和遠(yuǎn)程過程調(diào)用。 IPC是一種標(biāo)準(zhǔn)的Unix通信機(jī)制。

有兩種類型的進(jìn)程間通信(IPC)。
本地過程調(diào)用(LPC)LPC用在多任務(wù)操作系統(tǒng)中,使得同時運(yùn)行的任務(wù)能互相會話。這些任務(wù)共享內(nèi)存空間使任務(wù)同步和互相發(fā)送信息。
遠(yuǎn)程過程調(diào)用(RPC)RPC類似于LPC,只是在網(wǎng)上工作。RPC開始是出現(xiàn)在Sun微系統(tǒng)公司和HP公司的運(yùn)行UNIX操作系統(tǒng)的計算機(jī)中。
為什么RPC呢?就是無法在一個進(jìn)程內(nèi),甚至一個計算機(jī)內(nèi)通過本地調(diào)用的方式完成的需求,比如比如不同的系統(tǒng)間的通訊,甚至不同的組織間的通訊。由于計算能力需要橫向擴(kuò)展,需要在多臺機(jī)器組成的集群上部署應(yīng)用

RPC的核心并不在于使用什么協(xié)議。RPC的目的是讓你在本地調(diào)用遠(yuǎn)程的方法,而對你來說這個調(diào)用是透明的,你并不知道這個調(diào)用的方法是部署哪里。通過RPC能解耦服務(wù),這才是使用RPC的真正目的。RPC的原理主要用到了動態(tài)代理模式,至于http協(xié)議,只是傳輸協(xié)議而已。簡單的實現(xiàn)可以參考spring remoting,復(fù)雜的實現(xiàn)可以參考dubbo。
簡單的說,

RPC就是從一臺機(jī)器(客戶端)上通過參數(shù)傳遞的方式調(diào)用另一臺機(jī)器(服務(wù)器)上的一個函數(shù)或方法(可以統(tǒng)稱為服務(wù))并得到返回的結(jié)果。
RPC 會隱藏底層的通訊細(xì)節(jié)(不需要直接處理Socket通訊或Http通訊) RPC 是一個請求響應(yīng)模型。
客戶端發(fā)起請求,服務(wù)器返回響應(yīng)(類似于Http的工作方式) RPC 在使用形式上像調(diào)用本地函數(shù)(或方法)一樣去調(diào)用遠(yuǎn)程的函數(shù)(或方法)。
RPC通信過程
默認(rèn)socket通信。本地機(jī)器的RPC框架反序列化出執(zhí)行結(jié)果,函數(shù)return這個結(jié)果

RPC和restful api對比
REST是一種設(shè)計風(fēng)格,它的很多思維方式與RPC是完全沖突的。 RPC的思想是把本地函數(shù)映射到API,也就是說一個API對應(yīng)的是一個function,我本地有一個getAllUsers,遠(yuǎn)程也能通過某種約定的協(xié)議來調(diào)用這個getAllUsers。至于這個協(xié)議是Socket、是HTTP還是別的什么并不重要; RPC中的主體都是動作,是個動詞,表示我要做什么。 而REST則不然,它的URL主體是資源,是個名詞。而且也僅支持HTTP協(xié)議,規(guī)定了使用HTTP Method表達(dá)本次要做的動作,類型一般也不超過那四五種。這些動作表達(dá)了對資源僅有的幾種轉(zhuǎn)化方式。
RPC的根本問題是耦合。RPC客戶端以多種方式與服務(wù)實現(xiàn)緊密耦合,并且很難在不中斷客戶端的情況下更改服務(wù)實現(xiàn)。RPC更偏向內(nèi)部調(diào)用,REST更偏向外部調(diào)用。

Web 服務(wù)應(yīng)該算是 RPC 的一個子集,理論上 RPC 能實現(xiàn)的功能, 用 Web 服務(wù)也能實現(xiàn),甚至很多 RPC 框架選用 HTTP 協(xié)議作為傳輸層。
現(xiàn)在很多網(wǎng)站的 API 都是以 HTTP 服務(wù)的形式提供的,這也算是 RPC 的一種形式。

區(qū)別主要在這 2 個東西設(shè)計的出發(fā)點不太一樣:
HTTP 是面向瀏覽器設(shè)計的應(yīng)用層協(xié)議,操作的核心在資源。我們更多的用 Web 服務(wù)在做網(wǎng)站。
RPC 是為了在像在本地調(diào)用一個函數(shù)那樣調(diào)用遠(yuǎn)程的代碼而設(shè)計的,所以更關(guān)注減少本地調(diào)用和遠(yuǎn)程調(diào)用的差異,像 SOAP(簡單對象訪問協(xié)議) 這種東西是可以把對象當(dāng)參數(shù)傳的。
我們討論 RPC 和 Web 的區(qū)別,其實是在談?wù)?2 個東西:序列化協(xié)議和傳輸協(xié)議。序列化協(xié)議比如常見的 XML,JSON 和比較現(xiàn)代的 Protocol Buffers、Thrift。 傳輸協(xié)議比如 TCP、UDP 以及更高層的 HTTP 1.1、HTTP 2.0。

一般我們考慮用 RPC 而不是 HTTP 構(gòu)建自己的服務(wù),通常是考慮到下面的因素:
接口是否需要 Schema 約束
是否需要更高效的傳輸協(xié)議(TCP,HTTP 2.0)
是否對數(shù)據(jù)包的大小非常敏感
比如 HTTP 是基于文本的協(xié)議,頭部有非常多冗余(對于 RPC 服務(wù)而言)。HTTP 中我們用的最多就是 RESTful ,而 RESTful 是個弱 Schema 約束,大家通過文檔溝通,但是如果我就是不在實現(xiàn)的時候?qū)涌谖臋n約定的參數(shù)做檢查,你也不能把我怎么樣。這個時候 Thrift 這種序列化協(xié)議的優(yōu)勢就體現(xiàn)出來了,由于 Schema 的存在,可以保證服務(wù)端接受的參數(shù)和 Schema 保持一致。
RPC框架
Call ID映射。我們怎么告訴遠(yuǎn)程機(jī)器我們要調(diào)用Multiply,而不是Add或者FooBar呢?在本地調(diào)用中,函數(shù)體是直接通過函數(shù)指針來指定的,我們調(diào)用Multiply,編譯器就自動幫我們調(diào)用它相應(yīng)的函數(shù)指針。但是在遠(yuǎn)程調(diào)用中,函數(shù)指針是不行的,因為兩個進(jìn)程的地址空間是完全不一樣的。所以,在RPC中,所有的函數(shù)都必須有自己的一個ID。這個ID在所有進(jìn)程中都是唯一確定的。客戶端在做遠(yuǎn)程過程調(diào)用時,必須附上這個ID。然后我們還需要在客戶端和服務(wù)端分別維護(hù)一個 {函數(shù) <–> Call ID} 的對應(yīng)表。兩者的表不一定需要完全相同,但相同的函數(shù)對應(yīng)的Call ID必須相同。當(dāng)客戶端需要進(jìn)行遠(yuǎn)程調(diào)用時,它就查一下這個表,找出相應(yīng)的Call ID,然后把它傳給服務(wù)端,服務(wù)端也通過查表,來確定客戶端需要調(diào)用的函數(shù),然后執(zhí)行相應(yīng)函數(shù)的代碼。
序列化和反序列化。客戶端怎么把參數(shù)值傳給遠(yuǎn)程的函數(shù)呢?在本地調(diào)用中,我們只需要把參數(shù)壓到棧里,然后讓函數(shù)自己去棧里讀就行。但是在遠(yuǎn)程過程調(diào)用時,客戶端跟服務(wù)端是不同的進(jìn)程,不能通過內(nèi)存來傳遞參數(shù)。甚至有時候客戶端和服務(wù)端使用的都不是同一種語言(比如服務(wù)端用C++,客戶端用Java或者Python)。這時候就需要客戶端把參數(shù)先轉(zhuǎn)成一個字節(jié)流,傳給服務(wù)端后,再把字節(jié)流轉(zhuǎn)成自己能讀取的格式。這個過程叫序列化和反序列化。同理,從服務(wù)端返回的值也需要序列化反序列化的過程。
網(wǎng)絡(luò)傳輸。遠(yuǎn)程調(diào)用往往用在網(wǎng)絡(luò)上,客戶端和服務(wù)端是通過網(wǎng)絡(luò)連接的。所有的數(shù)據(jù)都需要通過網(wǎng)絡(luò)傳輸,因此就需要有一個網(wǎng)絡(luò)傳輸層。網(wǎng)絡(luò)傳輸層需要把Call ID和序列化后的參數(shù)字節(jié)流傳給服務(wù)端,然后再把序列化后的調(diào)用結(jié)果傳回客戶端。只要能完成這兩者的,都可以作為傳輸層使用。因此,它所使用的協(xié)議其實是不限的,能完成傳輸就行。盡管大部分RPC框架都使用TCP協(xié)議,但其實UDP也可以,而gRPC干脆就用了HTTP2。Java的Netty也屬于這層的東西。
目前有很多Java的RPC框架,有基于Json的,有基于XML,也有基于二進(jìn)制對象的。

論復(fù)雜度,RPC框架肯定是高于簡單的HTTP接口的。但毋庸置疑,HTTP接口由于受限于HTTP協(xié)議,需要帶HTTP請求頭,導(dǎo)致傳輸起來效率或者說安全性不如RPC

常用RPC框架
支持Java最多,golang
Netty - Netty框架不局限于RPC,更多的是作為一種網(wǎng)絡(luò)協(xié)議的實現(xiàn)框架,比如HTTP,由于RPC需要高效的網(wǎng)絡(luò)通信,就可能選擇以Netty作為基礎(chǔ)。
brpc是一個基于protobuf接口的RPC框架,在百度內(nèi)部稱為“baidu-rpc”,它囊括了百度內(nèi)部所有RPC協(xié)議,并支持多種第三方協(xié)議,從目前的性能測試數(shù)據(jù)來看,brpc的性能領(lǐng)跑于其他同類RPC產(chǎn)品。
Dubbo是Alibaba開發(fā)的一個RPC框架,遠(yuǎn)程接口基于Java Interface, 依托于Spring框架。
gRPC的Java實現(xiàn)的底層網(wǎng)絡(luò)庫是基于Netty開發(fā)而來,其Go實現(xiàn)是基于net庫。
Thrift是Apache的一個項目(http://thrift.apache.org),前身是Facebook開發(fā)的一個RPC框架,采用thrift作為IDL (Interface description language)。
jsonrpc
JSON-RPC
python web接口實現(xiàn)(restful方式、jsonrpc方式)
區(qū)塊鏈項目中用的較多?資料不是很多
JSON-RPC是一種序列化協(xié)議。JSON 是 JS 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質(zhì)是一個字符串。
非常簡單,方便,速度慢
相關(guān)Python 包(直接集成到flask和django)
Flask-JSONRPC,django-json-rpc;jsonrpcserver,jsonrpcclient

thrift
Python RPC 之 Thrift
Facebook開源的跨語言RPC框架。
gRPC
gRPC 官方文檔中文版
深入了解gRPC協(xié)議-知乎

tensorflow分布式與tensorflow serving底層通信都是是用的grpc
序列化用protobuf,通信使用http2
latest Google APIs will have gRPC versions of their interfaces, letting you easily build Google functionality into your applications.
支持 C, C++, Node.js, Python, Ruby, Objective-C,PHP and C#
HTTP2
HTTP/2 是 HTTP 協(xié)議自 1999 年 HTTP 1.1 發(fā)布后的首個更新,主要基于 SPDY 協(xié)議。
HTTP/2的主要目標(biāo)是通過啟用完整請求和響應(yīng)復(fù)用來減少延遲,通過有效壓縮HTTP頭字段來最大限度地降低協(xié)議開銷,并添加對請求優(yōu)先級和服務(wù)器推送的支持;多路復(fù)用(同一tcp,多個流),頭部壓縮,服務(wù)推送。

Protobuf
Protocol Buffers 是一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲格式,可以用于結(jié)構(gòu)化數(shù)據(jù)串行化,或者說序列化。它很適合做數(shù)據(jù)存儲或 RPC 數(shù)據(jù)交換格式。可用于通訊協(xié)議、數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)、平臺無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)格式。目前提供了 C++、Java、Python 三種語言的 API。
同 XML 相比, Protobuf 的主要優(yōu)點在于性能高。它以高效的二進(jìn)制方式存儲,比 XML 小 3 到 10 倍,快 20 到 100 倍。
框架選擇
如何選擇

什么時候應(yīng)該選擇gRPC而不是Thrift
  需要良好的文檔、示例
  喜歡、習(xí)慣HTTP/2、ProtoBuf
  對網(wǎng)絡(luò)傳輸帶寬敏感
什么時候應(yīng)該選擇Thrift而不是gRPC
  需要在非常多的語言間進(jìn)行數(shù)據(jù)交換
  對CPU敏感
  協(xié)議層、傳輸層有多種控制要求
  需要穩(wěn)定的版本
  不需要良好的文檔和示例

總的來說,Python rpc框架選擇較少,thrift性能最好,grpc性能比thrift稍差,原因是多了http2,而thrift直接基于tcp,但grpc序列化方案更通用(protobuf)優(yōu)秀,文檔較好;
jsonrpc 本身基于http/1進(jìn)行通信,速度最慢,相對于之前速度無提升,只是接口和數(shù)據(jù)格式更為統(tǒng)一;

gRPC不足
1)GRPC尚未提供連接池
2)尚未提供“服務(wù)發(fā)現(xiàn)”、“負(fù)載均衡”機(jī)制
3)因為基于HTTP2,絕大部多數(shù)HTTP Server、Nginx都尚不支持,即Nginx不能將GRPC請求作為HTTP請求來負(fù)載均衡,而是作為普通的TCP請求。(nginx將會在1.9版本支持)

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的RPC简介及框架选择的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。