深刻理解RPC——你看或沒看見 它都在那裏

隨着企業 IT 服務的不斷髮展,單臺服務器逐漸沒法承受用戶日益增加的請求壓力時,就須要多臺服務器聯合起來構成「服務集羣」共同對外提供服務。同時業務服務會隨着產品需求的增多愈來愈腫,架構上必須進行服務拆分,一個完整的大型服務會被打散成不少不少獨立的小服務,每一個小服務會由獨立的進程去管理來對外提供服務,這就是「微服務」。程序員

當用戶的請求到來時,咱們須要將用戶的請求分散到多個服務去各自處理,而後又須要將這些子服務的結果彙總起來呈現給用戶。那麼服務之間該使用何種方式進行交互就是須要解決的核心問題。RPC 就是爲解決服務之間信息交互而發明和存在的。spring

什麼是 RPC ?

RPC (Remote Procedure Call)即遠程過程調用,是分佈式系統常見的一種通訊方法,已經有 40 多年曆史。當兩個物理分離的子系統須要創建邏輯上的關聯時,RPC 是牽線搭橋的常見技術手段之一。除 RPC 以外,常見的多系統數據交互方案還有分佈式消息隊列、HTTP 請求調用、數據庫和分佈式緩存等。數據庫

其中 RPC 和 HTTP 調用是沒有通過中間件的,它們是端到端系統的直接數據交互。HTTP 調用其實也能夠當作是一種特殊的 RPC,只不過傳統意義上的 RPC 是指長鏈接數據交互,而 HTTP 通常是指即用即走的短連接。後端

RPC 在咱們熟知的各類中間件中都有它的身影。Nginx/Redis/MySQL/Dubbo/Hadoop/Spark/Tensorflow 等重量級開源產品都是在 RPC 技術的基礎上構建出來的,咱們這裏說的 RPC 指的是廣義的 RPC,也就是分佈式系統的通訊技術。RPC 在技術中的地位比如咱們身邊的空氣,它無處不在,可是又有不少人根本不知道它的存在。緩存

Nginx 與 RPC

Ngnix 是互聯網企業使用最爲普遍的代理服務器。它能夠爲後端分佈式服務提供負載均衡的功能,它能夠將後端多個服務地址聚合爲單個地址來對外提供服務。如圖,Django 是 Python 技術棧最流行的 Web 框架。性能優化

Nginx 和後端服務之間的交互在本質上也能夠理解爲 RPC 數據交互。也許你會爭辯說 Nginx 和後端服務之間使用的是 HTTP 協議,走的是短鏈接,嚴格上不能算是 RPC 調用。服務器

你說的沒錯,不過 Nginx 和後端服務之間還能夠走其它的協議,好比 uwsgi 協議、fastcgi 協議等,這兩個協議都是採用了比 HTTP 協議更加節省流量的二進制協議。如上圖所示,uWSGI 是著名的 Python 容器,使用它能夠啓動 uwsgi 協議的服務器對外提供服務。微信

uwsgi 通信協議在 Python 語言體系裏使用很是廣泛,若是一個企業內部使用 Python 語言棧搭建 Web 服務,那麼他們在生產環境部署 Python 應用的時候不是在使用 HTTP 協議就是在使用 uwsgi 協議來和 Nginx 之間創建通信。網絡

Fastcgi 協議在 PHP 語言體系裏很是常見,Nginx 和 PHP-fpm 進程之間通常較常使用 Fastcgi 協議進行通信。架構

Hadoop 與 RPC

在大數據技術領域,RPC 也佔據了很是重要的地位。大數據領域普遍應用了很是多的分佈式技術,分佈式意味着節點的物理隔離,隔離意味着須要通訊,通訊意味着 RPC 的存在。大數據須要通訊的量比業務系統更加龐大,因此在數據通訊優化上作的更深。

好比最多見的 Hadoop 文件系統 hdfs,通常包括一個 NameNode 和多個 DataNode,NameNode 和 DataNode 之間就是經過一種稱爲 Hadoop RPC 的二進制協議進行通信。

TensorFlow 與 RPC

在人工智能領域,RPC 也很重要,著名的 TensorFlow 框架若是須要處理上億的數據,就須要依靠分佈式計算力,須要集羣化,當多個分佈式節點須要集體智慧時,就必須引入 RPC 技術進行通信。Tensorflow Cluster 的 RPC 通信框架使用了 Google 內部自研的 gRPC 框架。

HTTP 調用其實也是一種特殊的 RPC

HTTP1.0 協議時,HTTP 調用還只能是短連接調用,一個請求來回以後鏈接就會關閉。HTTP1.1 在 HTTP1.0 協議的基礎上進行了改進,引入了 KeepAlive 特性能夠保持 HTTP 鏈接長時間不斷開,以便在同一個鏈接之上進行屢次連續的請求,進一步拉近了 HTTP 和 RPC 之間的距離。

當 HTTP 協議進化到 2.0 以後,Google 開源了一個創建在 HTTP2.0 協議之上的通訊框架直接取名爲 gRPC,也就是 Google RPC,這時 HTTP 和 RPC 之間已經沒有很是明顯的界限了。因此在後文咱們再也不明確強調 RPC 和 HTTP 請求調用之間的細微區別了,直接統一稱之爲 RPC。

HTTP VS RPC (普通話 VS 方言)

HTTP 與 RPC 的關係就比如普通話與方言的關係。要進行跨企業服務調用時,每每都是經過 HTTP API,也就是普通話,雖然效率不高,可是通用,沒有太多溝通的學習成本。可是在企業內部仍是 RPC 更加高效,同一個企業公用一套方言進行高效率的交流,要比通用的 HTTP 協議來交流更加節省資源。整個中國有很是多的方言,正若有不少的企業內部服務各有本身的一套交互協議同樣。雖然國家一直在提倡使用普通話交流,可是這麼多年過去了,你回一趟家鄉探個親什麼的就會發現身邊的人仍是流行說方言。

若是再深刻一點說,普通話本質上也是一種方言,只不過它是官方的方言,使用最爲普遍的方言,相比而言其它方言都是小語種,小語種之中也會有幾個使用比較普遍比較特點的方言佔比也會比較大。這就比如開源 RPC 協議中 Protobuf 和 Thrift 同樣,它們兩應該是 RPC 協議中使用最爲普遍的兩個。

換個角度看世界

若是兩個子系統沒有在網絡上進行分離,而是運行在同一個操做系統實例之上的兩個進程時,它們之間的通訊手段還能夠更加豐富。除了以上提到的幾種分佈式解決方案以外,還有共享內存、信號量、文件系統、內核消息隊列、管道等,本質上都是經過操做系統內核機制來進行數據和消息的交互而無須通過網絡協議棧。

但在現代企業服務中,這種單機應用已經很是少見了,由於單機應用意味着單點故障 —— 「一人摔跤全家跌倒」。業務子系統每每都須要經物理網絡棧進行隔離,所以分佈式解決方案在要求高可用無間斷服務的企業環境裏便大有做爲,這也讓 RPC 迎來本身大放異彩的時代。

前文提到的分佈式子系統交互方案,除了 RPC 技術以外還有數據庫、消息隊列和緩存。但其實這三者本質上是 RPC 技術的一個應用組合。咱們能夠將數據庫服務理解爲下面這張圖:

能夠看出,子系統和數據庫之間的交互也是經過 RPC 進行的,只不過這裏是三個子系統之間複雜的組合消息交互罷了。若是再深刻進去,你會發現,這裏的數據庫不是那種單機數據庫,而是具有主從複製功能的數據庫,好比 MySQL。在互聯網企業裏通常都會使用這種主從讀寫分離的數據庫。一個業務子系統將數據寫往主庫,主庫再將數據同步到從庫,而後另外一個業務子系統又從從庫裏將數據取出來。這時又能夠進一步將它們當作是四個子系統之間進行的更加複雜的 RPC 數據交互。

小結

如今,讀者應該能夠深入理解 RPC 在互聯網企業技術中的重要地位。從技術複雜性角度,也應該能夠明白爲何說對 RPC 技術的理解水平是評判一個程序員是否是高級程序員的重要標準之一。

在下一節,咱們將對 RPC 的交互原理進行深刻的學習,先把地基打牢,再開始實戰開發。

思考題

請讀者思考一下,在平時的後端開發中,還有哪些地方用到了「類 RPC」技術?

注:關注做者微信公衆號,瞭解更多分佈式架構、微服務、netty、MySQL、spring、JVM、性能優化、等知識點。

公衆號:《 Java大蝸牛 

相關文章
相關標籤/搜索