02.29 微服務調用為啥用RPC框架,http不更簡單嗎?

段勇賓


實際原因應該是比較簡單的,阿里構建dubbo應該是為了將單一系統分拆程多個系統,為了最小化減少已有系統改造的工作量,所以出現了rpc,目前在金融行業定長報文,變長報文等都是很成熟的,還有spring cloud,如果是一開始就搭建框架,建議用springcloud這樣的http協議,不建議用rpc這些框架,在跨語言調用的時候就會出現很大的問題


飄不遠了


RPC:Remote Procedure Call,中文意思就是遠程過程調用。

那麼我們先看看題目中的問題,其實,這個問題本身就是有問題的!


01. 既然有 HTTP ,為什麼還要用 RPC ?

HTTP 和 RPC 並不是兩個並行的概念,雖然很多書或文章,都介紹 HTTP 和 RPC 是在“應用層”,但實際上可以把應用層細分成多層,RPC 的所處的位置是高於 HTTP 的;HTTP 是網絡協議,而RPC 可以看做是一種編程模式或實現方案;

RPC 通常包含傳輸協議和序列化協議,單說傳輸協議,RPC 可以建立在 TCP 協議之上(比如 Dubbo),也可以建立在 HTTP 協議之上(比如 gRPC);如果是基於數據形式分類,RPC 又可以分成基於二進制、XML 和 JSON 三種;

而現在非常流行的開源 RPC 框架,比如上文中提到的Dubbo 和 gRPC 分別出身於阿里和谷歌,它們更多地是封裝了服務註冊發現、負載均衡、鏈路跟蹤等功能,也可以這麼理解,RPC 框架是對服務更高級的封裝。


02. RPC VS Restful 風格的 API

如果非要比較的話,可以比較 RPC 和 Restful 風格的 API。

  • RPC:面向過程,也就是要做一件什麼事情,只發送 GET 和 POST 請求;GET 用來查詢信息,其他情況下一律用 POST;請求參數是動詞。

  • RESTful:面向資源,這裡的資源可以是一段文字、一個文件、一張圖片,總之是一個具體的存在,可以使用 GET、POST、DELETE、PUT 請求,對應了增刪查改的操作;請求參數是名詞。

比如按照id 查找用戶:

  • 如果是 RPC 風格的 url 應該是這樣的:GET /queryUser?userid=xxx;

  • 而 RESTful 風格通常是這樣的:GET /user/{userid}


03. 究竟選擇哪一個?

RPC 特別適用於是分佈式環境;它讓客戶端進行遠程調用時,可以像調用本地方法一樣方便;RPC 框架屏蔽了很多底層的細節,開發人員不需要關注這些細節,比如序列化和反序列化、網絡傳輸協議;一些功能強大的 RPC 框架還提供了連接池管理、負載均衡、故障轉移、超時管理、上下文管理器、異步回調、收發包隊列、工作線程等功能。


RPC 和 Restful 風格的 API,如果非要爭出來個第一第二,那麼也要結合具體的使用場景,選擇更適合的那個。

如果是偏向內部的 API,提供的 API 很難進行資源的抽象,沒有規範的 API 的設計,性能要求更高,這些情況下更適合使用 RPC ;如果偏向外部 API,需要有更為規範的 API 設計,並且 API 天生是以資源為維度展開的,這時候可以選擇 Restful 風格的 API。

我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。


會點代碼的大叔


為什麼服務之間調用,選擇用RPC,http 不也能實現服務之間的通信嗎?怎麼不用呢?或者 RPC 比 http 好在哪裡?

什麼是RPC

提到RPC(Remote Procedure Call),就躲不開提到分佈式,這個促使RPC誕生的領域。

假設你有一個Calculator,以及它的實現類CalculatorImpl,那麼單體應用時,要調用Calculator的add方法來執行一個加運算,你可以方法中直接使用,因為在同一個地址空間,或者說在同一塊內存,這個稱為本地函數調用。

現在,將系統改造為分佈式應用,接口調用和實現分別在兩個子系統內,

服務A裡頭並沒有CalculatorImpl這個類,那它要怎樣調用服務B的CalculatorImpl的add方法呢?可以模仿B/S架構的調用方式,在B服務暴露一個Restful接口,然後A服務通過調用這個Restful接口來間接調用CalculatorImpl的add方法。

這樣,已經很接近RPC了,不過,像這種每次調用時,是不是都需要寫一串發起http請求的代碼呢?比如httpClient.sendRequest...之類的,能不能簡單一下,像本地方法調用一樣,去發起遠程調用,讓使用者感知不到遠程調用的過程。

屏蔽的工作,可以使用代理模式解決,生成一個代理對象,而這個代理對象的內部,就是通過httpClient來實現RPC遠程過程調用的。

這就是很多RPC框架要解決的問題和解決的思路,比如阿里的Dubbo。

總結一下,RPC要解決的兩個問題:

1. 解決分佈式系統中,服務之間的調用問題。

2. 遠程調用時,要能夠像本地調用一樣方便,讓調用者感知不到遠程調用的邏輯。

RPC是一種技術的概念名詞

RPC=Remote Produce Call 是一種技術的概念名詞,HTTP是一種協議,RPC可以通過 HTTP 來實現,也可以通過Socket自己實現一套協議來實現.所以題目可以換一種理解,為何 RPC 還有除 HTTP 之外的實現法,有何必要,畢竟除了HTTP實現外,私有協議不具備通用性.

RPC框架好處

http接口是在接口不多、系統與系統交互較少的情況下,解決信息孤島初期常使用的一種通信手段;

優點就是簡單、直接、開發方便。

如果是一個大型的網站,內部子系統較多、接口非常多的情況下,RPC框架的好處就顯示出來了:

首先就是長鏈接,不必每次通信都要像http一樣去3次握手什麼的,減少了網絡開銷;

其次就是RPC框架一般都有註冊中心,有豐富的監控管理;發佈、下線接口、動態擴展等,對調用方來說是無感知、統一化的操作。

最後是安全性。

rpc是一種概念,http也是rpc實現的一種方式。

論複雜度,dubbo/hessian用起來是超級簡單的。

至於為什麼用dubbo/hessian,有幾點:

一是調用簡單,真正提供了類似於調用本地方法一樣調用接口的功能 。

二是參數返回值簡單明瞭 參數和返回值都是直接定義在jar包裡的,不需要二次解析。

三是 輕量,沒有多餘的信息。

四是便於管理,基於dubbo的註冊中心。

RPC能解耦服務

RPC:遠程過程調用。RPC的核心並不在於使用什麼協議。RPC的目的是讓你在本地調用遠程的方法,而對你來說這個調用是透明的,你並不知道這個調用的方法是部署哪裡。

通過RPC能解耦服務,這才是使用RPC的真正目的。RPC的原理主要用到了動態代理模式,至於http協議,只是傳輸協議而已。簡單的實現可以參考spring remoting,複雜的實現可以參考dubbo。

rpc=socket + 動態代理

服務器通訊原理就是一臺socket服務器A,另一臺socket客戶端B,現在如果要通訊的話直接以流方式寫入或讀出。這樣能實現通訊,但有個問題。如何知道更多信息?

比如需要發送流大小,編碼,Ip等。這樣就有了協議,協議就是規範,就是發送的流中攜帶了很多的內容。那回到剛剛的問題。發送的內容就是文本類型,客戶端就得序列化,那麼常用的就有json,xml之類,如果想把內容變得更小,那就有二進制了。把文本變成二進制傳遞。

說到 rpc 與http接口,不要太複雜了。rpc 協議更簡單內容更小,那麼來說效率是要高一點

rpc 是什麼?就是socket 加動態代理。

總結

學技術應該是知其然知其所以然,我們得明白什麼場景,或者什麼業務需要它,它能解決其他技術不能解決或者不方便解決的問題。

RPC是一個軟件結構概念,是構建分佈式應用的理論基礎。就好比為啥你家可以用到發電廠發出來的電?是因為電是可以傳輸的。至於用銅線還是用鐵絲還是其他種類的導線,也就是用http還是用其他協議的問題了。這個要看什麼場景,對性能要求怎麼樣。

在java中的最基本的就是RMI技術,它是java原生的應用層分佈式技術。我們可以肯定的是在傳輸性能方面,RMI的性能是優於HTTP的。

那為啥很少用到這個技術?那是因為用這個有很多侷限性,首先它要保證傳輸的兩端都要要用java實現,且兩邊需要有相同的對象類型和代理接口,不需要容器,但是加大了編程的難度,在應用內部的各個子系統之間還是會看到他的身影,比如EJB就是基於rmi技術的。

這就與目前的bs架構的軟件大相徑庭。用http必須要服務端位於http容器裡面,這樣減少了網絡傳輸方面的開發,只需要關注業務開發即可。所以在架構一個軟件的時候,不能一定根據需求選定技術。


Java架構達人


微服務調用為啥用RPC框架,Http不更簡單嗎?

背景

在一次的面試交談中,聊到業務實現的技術架構。不管系統大小,一般都是微服務的架構,所以就產生了一個問題,為什麼服務之間調用,選擇用RPC,http 不也能實現服務之間的通信嗎?怎麼不用呢?或者 RPC 比 http 好在哪裡?

什麼是RPC

提到RPC(Remote Procedure Call),就躲不開提到分佈式,這個促使RPC誕生的領域。

假設你有一個Calculator,以及它的實現類CalculatorImpl,那麼單體應用時,要調用Calculator的add方法來執行一個加運算,你可以方法中直接使用,因為在同一個地址空間,或者說在同一塊內存,這個稱為本地函數調用。

現在,將系統改造為分佈式應用,接口調用和實現分別在兩個子系統內,

服務A裡頭並沒有CalculatorImpl這個類,那它要怎樣調用服務B的CalculatorImpl的add方法呢?可以模仿B/S架構的調用方式,在B服務暴露一個Restful接口,然後A服務通過調用這個Restful接口來間接調用CalculatorImpl的add方法。

這樣,已經很接近RPC了,不過,像這種每次調用時,是不是都需要寫一串發起http請求的代碼呢?比如httpClient.sendRequest...之類的,能不能簡單一下,像本地方法調用一樣,去發起遠程調用,讓使用者感知不到遠程調用的過程。

屏蔽的工作,可以使用代理模式解決,生成一個代理對象,而這個代理對象的內部,就是通過httpClient來實現RPC遠程過程調用的。

這就是很多RPC框架要解決的問題和解決的思路,比如阿里的Dubbo。

總結一下,RPC要解決的兩個問題:

1. 解決分佈式系統中,服務之間的調用問題。

2. 遠程調用時,要能夠像本地調用一樣方便,讓調用者感知不到遠程調用的邏輯。

RPC是一種技術的概念名詞

RPC=Remote Produce Call 是一種技術的概念名詞,HTTP是一種協議,RPC可以通過 HTTP 來實現,也可以通過Socket自己實現一套協議來實現.所以題目可以換一種理解,為何 RPC 還有除 HTTP 之外的實現法,有何必要,畢竟除了HTTP實現外,私有協議不具備通用性.

RPC框架好處

http接口是在接口不多、系統與系統交互較少的情況下,解決信息孤島初期常使用的一種通信手段;

優點就是簡單、直接、開發方便。

如果是一個大型的網站,內部子系統較多、接口非常多的情況下,RPC框架的好處就顯示出來了:

首先就是長鏈接,不必每次通信都要像http一樣去3次握手什麼的,減少了網絡開銷;

其次就是RPC框架一般都有註冊中心,有豐富的監控管理;發佈、下線接口、動態擴展等,對調用方來說是無感知、統一化的操作。

最後是安全性。

rpc是一種概念,http也是rpc實現的一種方式。

論複雜度,dubbo/hessian用起來是超級簡單的。

至於為什麼用dubbo/hessian,有幾點:

一是調用簡單,真正提供了類似於調用本地方法一樣調用接口的功能 。

二是參數返回值簡單明瞭 參數和返回值都是直接定義在jar包裡的,不需要二次解析。

三是 輕量,沒有多餘的信息。

四是便於管理,基於dubbo的註冊中心。

RPC能解耦服務

RPC:遠程過程調用。RPC的核心並不在於使用什麼協議。RPC的目的是讓你在本地調用遠程的方法,而對你來說這個調用是透明的,你並不知道這個調用的方法是部署哪裡。

通過RPC能解耦服務,這才是使用RPC的真正目的。RPC的原理主要用到了動態代理模式,至於http協議,只是傳輸協議而已。簡單的實現可以參考spring remoting,複雜的實現可以參考dubbo。

rpc=socket + 動態代理

服務器通訊原理就是一臺socket服務器A,另一臺socket客戶端B,現在如果要通訊的話直接以流方式寫入或讀出。這樣能實現通訊,但有個問題。如何知道更多信息?

比如需要發送流大小,編碼,Ip等。這樣就有了協議,協議就是規範,就是發送的流中攜帶了很多的內容。那回到剛剛的問題。發送的內容就是文本類型,客戶端就得序列化,那麼常用的就有json,xml之類,如果想把內容變得更小,那就有二進制了。把文本變成二進制傳遞。

說到 rpc 與http接口,不要太複雜了。rpc 協議更簡單內容更小,那麼來說效率是要高一點

rpc 是什麼?就是socket 加動態代理。

總結

學技術應該是知其然知其所以然,我們得明白什麼場景,或者什麼業務需要它,它能解決其他技術不能解決或者不方便解決的問題。

RPC是一個軟件結構概念,是構建分佈式應用的理論基礎。就好比為啥你家可以用到發電廠發出來的電?是因為電是可以傳輸的。至於用銅線還是用鐵絲還是其他種類的導線,也就是用http還是用其他協議的問題了。這個要看什麼場景,對性能要求怎麼樣。

在java中的最基本的就是RMI技術,它是java原生的應用層分佈式技術。我們可以肯定的是在傳輸性能方面,RMI的性能是優於HTTP的。

那為啥很少用到這個技術?那是因為用這個有很多侷限性,首先它要保證傳輸的兩端都要要用java實現,且兩邊需要有相同的對象類型和代理接口,不需要容器,但是加大了編程的難度,在應用內部的各個子系統之間還是會看到他的身影,比如EJB就是基於rmi技術的。

這就與目前的bs架構的軟件大相徑庭。用http必須要服務端位於http容器裡面,這樣減少了網絡傳輸方面的開發,只需要關注業務開發即可。所以在架構一個軟件的時候,不能一定根據需求選定技術。


三年起步


RPC名稱是遠程服務調用。這裡面實際是沒有限制一定會是tcp,也可以是http或者其他基於tcp協議的服務。

遠程服務調用,有多種 ,http的接口調用,基於http的webservice,java中的rmi 實際都算是rpc。為什麼都向長連接改動。是因為技術性能的要求越來越高,必然帶來這樣的發展趨勢。

http接口,簡單通用,但是調用放需要編寫大量的代碼去解析返回結果,並且http性能並不高效,除了header的問題之外,早期的http還不能多路複用。

webservice實際上是http協議之上的封裝,它更多是為了解決http接口調用需要編寫大量客戶端解析參數代碼產生的,它能幫助少寫代碼,但無法改善http的性能。

java的rmi 典型的就是ejb 現在新的java程序員可能都沒聽過這玩意,這也是基於長連接實現,基於java的序列化。它能夠解決客戶端參數解析的問題,也能多路複用socket 但是ejb本身的複雜性以及java序列化低效的問題導致它也是被放棄,並且它是不能跨語言的。

現在的rpc框架大多都是基於socket長連接,自定義協議實現。採用的序列化方式也會比較高效和跨語言。比如grpc 採用protobuf做序列化,採用http2做傳輸協議。

從某種意義上來講,http接口也能算是rpc調用,只是需要更具開發工作量以及性能指標做技術抉擇。


LKC444


都沒說到點子上。微服務使用的RPC是基於HTTP2的gRPC,傳輸格式使用binary的protobuf,比json更快,HTTP2支持multiplexing, concurrency, streaming。


Yan142040965


首先微服務也有用http的,現在流行的feign,底層就是http,也是我們經常提到的restful編程方式。

Rpc在國內最具有代表的是dubbo,底層可以選擇netty進行通訊,速度肯定是比http快的。

但是微服務不是一個簡單的調用,涉及到很多方面,比如容錯,高併發,熔斷,事務等等。普通的http代碼是無法解決這些問題的。一般需要很多組件來配合,比如feign就要配合robbin,hystrix等來配合,dubbo也需要zookeeper來配合。

所以這兩者在我們的開發中,都很常見。


老牛視頻剪輯


RPC只是微服務使用的一種協議,微服務也支持HTTP。

RPC都提出了超過20年了,微服務提出才不到10年。

微服務是SOA基礎上進化而來的,解決的是傳統繼承方案的中心化部署(從而導致不宜擴展)、臃腫(服務太大粒度不夠小)等問題。


子非魚137819


微服務強調的是傳輸效率,http傳輸效率過低,攜帶頭部信息影響傳輸更多的信息,而rpc是一種專門設計用來進行遠程調用的消息傳輸機制,傳輸效率高,微服務非常強調時延性,而rpc解決了這個問題,所以大家更喜歡使用它。

但是沒有任何事情是絕對的,畢竟http相比較而言,更加方便,有時候也會使用它。


夢迴故里歸來


rpc異步非阻塞多線程,http同步阻塞單線程服務足夠微,效率也不比rpc差,服務太小太多小項目成本也很高。所以看情況用。http也可以用mq做異步非阻塞提高效率,成本也很高。


分享到:


相關文章: