fresh-tech-lab / fenix-study-group

A study group for tracking our progress
MIT License
10 stars 0 forks source link

第二章:存取遠端服務 學習要點 #2

Open emily40830 opened 10 months ago

emily40830 commented 10 months ago

存取遠端服務

adrian-lin-1-0-0 commented 10 months ago

訪問遠程服務

RPC (Remote Procedure Call)

IPC (Inter-Process Communication)

通信成本

8 Fallacies of Distributed Computing

三個基本問題

REST 設計風格

HTTP

REST 六大原則

REST 不足

Idempotency key

如何生成Idempotency key?

Clean Architecture / DDD 都不喜歡依賴資料庫

如何儲存Idempotency key?

試比較不同類型Idempotency key在不同data structure儲存中的搜尋效率

  • B+ Tree
  • Hash
shihgangliu commented 10 months ago

進程間通訊(IPC)有下面幾種方法:

  1. 管道(pipe):進程間可以通過管道傳遞少量的 streaming
  2. 信號(signal):信號是用來通知目標進程有某件事發生
  3. 信號量(semaphore):兩個進程間同步協作的方式
  4. 消息對列(message queue):和以上三者不同的是可以處理較大量的資料,但缺乏即時性
  5. 共享內存(shared memory):多個進程訪問同一個公共內存空間,是效率最高的進程間通訊
  6. 套接字接口(socket):socket 的特色是唯一可以支援不同機器彼此進程間的通訊

通訊的成本

socket 發明者和一眾人在20世紀末發表了網路通訊進行分佈式運算的八宗罪:

  1. The network is reliable
  2. Latency is zero
  3. Bandwidth is infinite
  4. The network is secure
  5. Topology doesn't change
  6. There is one administrator
  7. Transport cost is zero
  8. The network is homogeneous

遠程調用常見的三大問題以及基本解法

  1. 如何表示數據:序列化和反序列化
  2. 如何傳遞數據:Wire Protocol
  3. 如何確定方法:Interface Description Language

從統一到分裂的 RPC 發展

  1. 面向對象:早期的 CORBA、DCOM
  2. 面向性能:gRPC、Thrift
  3. 面向簡化:JSON-RPC

REST 設計風格

面向資源編成,沒有一定的規範和強制性。Representational State Transfer 可以視為 Hypertext Transfer(HTT)的進一步抽象。

RESTful 的系統

  1. 用戶端與客戶端分離
  2. 無狀態
  3. 可緩存
  4. 分層系統
  5. 統一接口
  6. 按需代碼

RMM 成熟度

outshaker commented 10 months ago

ch2 訪問遠端服務

遠端服務調用 Remote Procedure Call,RPC

解決什麼問題 如何解決這些問題 為什麼要這樣解決

進程間通信 IPC

最初目的:「為了讓計算機能夠跟調用本地方法一樣去調用遠端方法」

為了解決兩個進程之間通訊的議題有以下作法:

  1. Pipe, Named Pipe 管道 具名管道
  2. Signal 信號。進程可以自己決定要對 Signal 做什麼樣的反應,這部分並沒有統一標準
  3. Semaphore 信號量。
  4. Message Queue 訊息佇列。傳輸量比較大
  5. Shared Memory 共用記憶體。效率最高,會搭配其他機制實現互斥或同步操作
  6. Socket 套接字介面,有機會跨主機的進程間通信。UNIX Domain Socket, IPC Socket

通信成本

IPC Socket 成為網路和本地共通的通訊介面,有很大的吸引力。

「透明的 RPC 調用」造成的錯誤認知:通信是無成本的假像

八宗罪: The network is reliable —— 網路是可靠的。 Latency is zero —— 延遲是不存在的。 Bandwidth is infinite —— 带寬是無限的。 The network is secure —— 網路是安全的。 Topology doesn't change —— 拓撲結構是一成不變的。 There is one administrator —— 總會有一個管理員。 Transport cost is zero —— 不必考慮傳輸成本。 The network is homogeneous —— 網络是同質化的。

如果遠端服務調用要弄透明化的話,就必須為這些罪過埋單

最早完整的 RPC 概念提出者:80 年代初期,施樂 Palo Alto 研究中心 Cedar 語言的 RPC 框架 Lupine

Remote procedure call is the synchronous language-level transfer of control between programs in disjoint address spaces whose primary communication medium is a narrow channel.

遠端服務調用是指位於互不重合的記憶體位址空間中的兩個程式,在語言層面上,以同步的方式使用頻寬有限的通道來傳輸程式控制資訊。

三個基本的問題

  1. 如何表示數據 => (介質) 序列化/反序列化
  2. 如何傳遞數據 => 傳輸協定
  3. 如何確定方法 => IDL

統一的 RPC

1991 CORBA 呈現大一統的姿態,但很可惜沒有成功 1998 W3C 組織成立,XML 1.0 1999 SOAP 1.0 規範發布 => 名為 web service 的 RPC 協定誕生

結論:上面的東西都很難用,簡單、通用、高性能很難同時滿足

分裂的 RPC

不再追求完美,而是夠用就好。

改變方向:

  1. 物件導向 => 取代過程導向

  2. 性能 => gRPC, Thrift

  1. 簡化 => JSON-RPC
    • JSON-RPC: 適合 web 瀏覽器

未來發展:

反思: 開發一個分散式系統,是不是就一定要用 RPC 呢? RPC 的三大問題源自於對本地方法調用的類比類比類比,如果我們把思維從“方法調用”的約束中掙脫,那參數與結果如何表示、方法如何表示、數據如何傳遞這些問題都會海闊天空,擁有煥然一新的視角。 但是我們寫程式,真的可能不面向方法來程式設計嗎?

REST 設計風格

REST 與 RPC 都不盡相同,充其量只能算是有一些相似,應用會有一部分重合之處,但本質上並不是同一類型的東西 抽象的目標不一樣 => 面向資源程式設計 REST 只能說是風格而不是規範、協議

理解 REST

资源(Resource) => 對應一個內容 表征(Representation) => 表徵指的是內容的表現形式 HTML 或 PDF 都可以是一種表徵,表現層 状态(State) => 上下文,主機需要紀錄客戶端某些資料才有辦法正確執行就是狀態 转移(Transfer) => 一旦伺服器透過某種方式改變了「狀態」,就稱為「表徵狀態轉移」

统一接口(Uniform Interface) => URI, method (GET, POST...) 超文本驱动(Hypertext Driven) => 以網頁做為驅動狀態轉移的介質,ex: 存取網頁 & 在網頁上點選連結 自描述消息(Self-Descriptive Messages) => 透過 Content-Type 取得想要的內容

RESTful 的系统

服务端与客户端分离(Client-Server) => 關注點分離,提升可移植性 无状态(Stateless) => 目前大部分系統無法滿足此要求 可缓存(Cacheability) => 可以跟 server 溝通快取相關的資訊 分层系统(Layered System) => 用戶不需要知道中間經過了那些主機(server) 统一接口(Uniform Interface) => 通常會借用 http 本身的 method 完成,通常面向資源的設計通用程度比較好 按需代码(Code-On-Demand) => 非必須。根據用戶端的需要發送可執行的代碼給他

=> 面向資源的設計風格是 HTTP 30 年來發展的習慣,如果能匹配的話,效率和拓展性會很可觀

RMM 成熟度

分成 0 - 3 級

不足与争议

面向资源的编程思想只适合做 CRUD,面向过程、面向对象编程才能处理真正复杂的业务逻辑 REST 与 HTTP 完全绑定,不适合应用于要求高性能传输的场景中 REST 不利于事务支持 REST 没有传输可靠性支持 REST 缺乏对资源进行“部分”和“批量”的处理能力

emily40830 commented 10 months ago
  1. 要讓 RPC 透明化,如同本地調用的體感,則要付上一些代價,這些代價也稱為透過網路進行分散式運算的八宗罪,意旨這些謬誤不成立,RPC 才能免強作為 IPC 的一種
  2. RPC 1050 是一項面對廣義網路或混合網路環境,基於 TCP/IP,使用 C 語言的 RPC 協議,也演變成後續各種 RPC 協議的實現所依循的框架
  3. 實現 RPC 協議不外乎都是在處理三個問題:如何表示數據(序列化與反序列化)、傳遞數據(如何透過網路將兩個 endpoint 之間的訊息做交換,其中包含了驗證與安全等議題)、與表示方法(跨語言共用的介面 IDL)
  4. RPC 的統一與分裂,最後認清了簡單、普適、高效能這三點難以同時滿足,因此漸漸朝著特色發展,主要分為 物件導向、效能、簡易三個面向
  5. REST 是一種以資源為導向的風格。RMM 是一種用來衡量系統有多 RESTFUL 的等級,大多數的系統都有達到 第 2 級,然而第三級 Hypermedia control 則趨於少見,要達到第三級,才有辦法將服務端的 API 與 Client 完全解耦
HuaYuan-Tseng commented 10 months ago

筆記連結:Link

Carisa-Li commented 10 months ago

學習要點

IPC 進程間通信(Inter-Process Communication)

RPC遠程服務調用(Remote Procedure Call) 一開始試圖模擬IPC,想讓實際應用兩者時,程式碼一致

RPC成為語言層次而非系統層次的特徵

近幾年RPC框架逐漸關注更高層次的需求,並朝插件化及可擴展性(使用者可自行調整傳輸協議、序列化器等)發展

REST設計風格(REpresentational State Transfer) 以資源為主體的設計風格

kehao-chen commented 10 months ago

學習要點

吃 🍉 為主,隨筆撰寫

共享内存(Shared Memory) 允许多个进程可以访问同一块内存空间,这是效率最高的进程间通讯形式。

Shared Memory 之所以效率最高,主要是少了資料複製的成本,以 IPC 來說需要將訊息在 User Space 與 Kernel Space 之間複製傳輸,而使用 Shared Memory 只要將其映射到 process 所處的虛擬定址空間

image image

圖片來源:Inter-Process Communication - Operating System Notes

针对那些比较抽象的场景,如果确实不好把 HTTP 方法映射为资源的所需操作,REST 也并不会刻板地要求一定要做映射。这时,用户可以使用自定义方法,按 Google 推荐的 REST API 风格来拓展 HTTP 标准方法。 自定义方法应该放在资源路径末尾,嵌入冒号加自定义动词的后缀。比如,我将删除操作映射到标准 DELETE 方法上,此外还要提供一个恢复删除的 API,那它可能会被设计为:

POST /user/user_id/cart/book_id:undelete

image

linxinemily commented 10 months ago

進度緩慢地吃瓜

訪問遠程服務

遠程服務調用(RPC)

RPC(Remote procedure call),是指位於互不重合的內存地址空間中的兩個程序,在語言層面上,以同步的方式使用頻寬有限的信道來傳輸程序控制訊息。

兩個進程之間交換數據稱之為進程間通信(Inter-Process Communication,IPC),方法有幾種:

其中前三種(Pipe、Signal、Semaphore)只適合傳遞少量訊息,Shared Memory 效率最高, Socket 則可用於不同機器之間的通信。

RPC 的三個基本問題

RPC 協議的演進歷史

  1. DCE/RPC、ONC RPC 只支持傳遞值、結構體而非對象
  2. CORBA 支持物件導向的服務調用,並支持跨系統、跨語言,惟繁瑣為人詬病
  3. Web Service 採用當時紅於一時的 XML 作為編碼載體,一大缺點是過於嚴格的數據和接口定義所帶來的性能問題

一直沒有能滿足“簡單”、“普適”、“高性能”三點的“完美 RPC 協議“,時至今日,整體也不再追求大而全的完美,而是以不同特點作為主要的發展方向:

REST 設計風格

REST v.s. RPC

兩者抽象的目標不一樣,REST 面向資源(Resource Oriented);RPC 面向過程(Procedure Oriented)。概念上也不同,REST 並非協議,只是風格。而在使用範圍上,兩者都屬於主流的遠程調用方式。

REST 相關名詞概念

為“表徵狀態轉移”的縮寫(Representational State Transfer),實際上是“HTT”(Hypertext Transfer)的進一步抽象

HTTP 中使用的“超文本(Hypertext)”(或超媒體,Hypermedia)指的是一種能夠對操作進行分支判斷和差異響應的文本(或聲音、圖像)

  1. 資源(Resource):當瀏覽器向服務端發出請求,取得文章內容,這篇文章的內容本身稱之為”資源“
  2. 表徵(Representation):服務器向瀏覽器返回的 HTML 就是該資源的其中一種“表徵”,同一份資源可能有多種其他“表徵”(如 PDF)
  3. 狀態:使用者想看“下一篇文章”時,會需要傳遞”當前是在哪一份文章”的資訊給服務器,這類在特定語境中才能產生的上下文訊息稱之為“狀態”
  4. 轉移:服務器透果某種方式,將用戶當前閱讀的文章轉變成下一篇文章,稱之為“表徵狀態轉移”
  5. 統一接口:HTTP 協議中約定好七種基本操作,針對特定的 URI 採取這些操作,服務器就會觸發相應的表徵狀態轉移
  6. 超文本驅動:任何狀態轉移行為都不是預置於瀏覽器代碼中,而是由服務器發出的請求響應信息(超文本)來驅動
  7. 自描述消息:在給客戶端的訊息中,要明確告知客戶端消息的類型和應如何處理這段消息,例如於 Content-Type Header 中標示 MIME type

理想的 RESTful 系統六大原則

  1. 服務端與客戶端分離
  2. 無狀態(大型且複雜的系統往往愈難達到)
  3. 可緩存:無狀帶會降低系統的網路性,因此允許客戶端或中間的代理能像部分服務端的回應緩存

降低系統的網路性:某功能如果使用有狀態的設計只需少量的請求就能達成,使用無狀態會需要多次或攜帶冗余訊息的請求

  1. 分層系統:客戶端不需要知道是否直接連接到最終的服務器,或是路徑上中間的服務器。典型應用為 CDN。
  2. 統一接口:希望面向資源編程,而非面向服務。面向資源的抽象程度通常更高。
  3. 按需代碼

REST 的好處

REST 的程度分級

由低至高

Level Name Description
0 The Swamp of Plain Old XML 完全不 REST
1 Resources 開始引入資源的概念
圍繞著資源而非過程來設計
服務的 Endpoint 應該是名詞而非動詞
2 HTTP Verbs 引入統一接口,映射到 HTTP 協議的方法上
3 Hypermedia Controls 超文本驅動,“Hypertext As The Engine Of Application State,HATEOAS”
服務器傳回的響應訊息應包括可能的後續操作:實現狀態轉移的其他 endpoint
服務端 API 和客戶端是完全解耦的

REST 的不足與爭議

此處的“事務”指的是通過服務協議或架構,在分布式服務中獲得對多個數據同時提交的統一協調能力(2PC/2PC)

  • 沒有傳輸可靠性支持*
  • 缺乏對資源進行“部分”和“批量”的處理能力

個人小結/心得

在這之前從來沒覺得 RPC 和 REST 這兩個名詞/概念是可以被放在一起比較的,但這裡用了一個比較高階的視角看待兩者。RPC 和 REST 被創造出來,都有為了“呼叫或存取網路上其他服務器的資源”的目的(也就是本章的主題——訪問遠程服務),只是一個(RPC)基於面向過程,一個(REST)基於面向資源,後者又比前者更抽象,更遠離人類的直覺思考,也因此能更加通用。

RPC 相對 REST 的高效、接近電腦世界中主流的交互方式,較適合存在於服務器之間的溝通;而 REST 基於 HTTP 協議,奠基於應用層,符合網路世界的主流交互方式,較適合存在於服務器與客戶端之間的溝通。