Open emily40830 opened 1 year ago
linux kernel 中提供
ipc/mqueue.c
AF_UNIX
Using AF_UNIX address family
這裡bind的是檔案路徑8 Fallacies of Distributed Computing
這句話是說所有人的網路環境都一致嗎?
Idempotent function
以TCP segment
的header
為例,在request
上加入識別碼
idempotent requests 在 header 加入 Idempotency-Key
curl https://api.stripe.com/v1/customers \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-H "Idempotency-Key: 5th1sTHykc3Eff8G" \
-d description="My First Test Customer (created for API docs at https://www.stripe.com/docs/api)"
Clean Architecture / DDD 都不喜歡依賴資料庫
試比較不同類型
Idempotency key
在不同data structure
儲存中的搜尋效率
- B+ Tree
- Hash
socket 發明者和一眾人在20世紀末發表了網路通訊進行分佈式運算的八宗罪:
面向資源編成,沒有一定的規範和強制性。Representational State Transfer 可以視為 Hypertext Transfer(HTT)的進一步抽象。
ch2 訪問遠端服務
遠端服務調用 Remote Procedure Call,RPC
解決什麼問題 如何解決這些問題 為什麼要這樣解決
最初目的:「為了讓計算機能夠跟調用本地方法一樣去調用遠端方法」
為了解決兩個進程之間通訊的議題有以下作法:
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.
遠端服務調用是指位於互不重合的記憶體位址空間中的兩個程式,在語言層面上,以同步的方式使用頻寬有限的通道來傳輸程式控制資訊。
1991 CORBA 呈現大一統的姿態,但很可惜沒有成功 1998 W3C 組織成立,XML 1.0 1999 SOAP 1.0 規範發布 => 名為 web service 的 RPC 協定誕生
結論:上面的東西都很難用,簡單、通用、高性能很難同時滿足
不再追求完美,而是夠用就好。
改變方向:
物件導向 => 取代過程導向
性能 => gRPC, Thrift
未來發展:
反思: 開發一個分散式系統,是不是就一定要用 RPC 呢? RPC 的三大問題源自於對本地方法調用的類比類比類比,如果我們把思維從“方法調用”的約束中掙脫,那參數與結果如何表示、方法如何表示、數據如何傳遞這些問題都會海闊天空,擁有煥然一新的視角。 但是我們寫程式,真的可能不面向方法來程式設計嗎?
REST 與 RPC 都不盡相同,充其量只能算是有一些相似,應用會有一部分重合之處,但本質上並不是同一類型的東西 抽象的目標不一樣 => 面向資源程式設計 REST 只能說是風格而不是規範、協議
资源(Resource) => 對應一個內容 表征(Representation) => 表徵指的是內容的表現形式 HTML 或 PDF 都可以是一種表徵,表現層 状态(State) => 上下文,主機需要紀錄客戶端某些資料才有辦法正確執行就是狀態 转移(Transfer) => 一旦伺服器透過某種方式改變了「狀態」,就稱為「表徵狀態轉移」
统一接口(Uniform Interface) => URI, method (GET, POST...) 超文本驱动(Hypertext Driven) => 以網頁做為驅動狀態轉移的介質,ex: 存取網頁 & 在網頁上點選連結 自描述消息(Self-Descriptive Messages) => 透過 Content-Type 取得想要的內容
服务端与客户端分离(Client-Server) => 關注點分離,提升可移植性 无状态(Stateless) => 目前大部分系統無法滿足此要求 可缓存(Cacheability) => 可以跟 server 溝通快取相關的資訊 分层系统(Layered System) => 用戶不需要知道中間經過了那些主機(server) 统一接口(Uniform Interface) => 通常會借用 http 本身的 method 完成,通常面向資源的設計通用程度比較好 按需代码(Code-On-Demand) => 非必須。根據用戶端的需要發送可執行的代碼給他
=> 面向資源的設計風格是 HTTP 30 年來發展的習慣,如果能匹配的話,效率和拓展性會很可觀
分成 0 - 3 級
面向资源的编程思想只适合做 CRUD,面向过程、面向对象编程才能处理真正复杂的业务逻辑 REST 与 HTTP 完全绑定,不适合应用于要求高性能传输的场景中 REST 不利于事务支持 REST 没有传输可靠性支持 REST 缺乏对资源进行“部分”和“批量”的处理能力
筆記連結:Link
IPC 進程間通信(Inter-Process Communication)
RPC遠程服務調用(Remote Procedure Call) 一開始試圖模擬IPC,想讓實際應用兩者時,程式碼一致
RPC成為語言層次而非系統層次的特徵
近幾年RPC框架逐漸關注更高層次的需求,並朝插件化及可擴展性(使用者可自行調整傳輸協議、序列化器等)發展
REST設計風格(REpresentational State Transfer) 以資源為主體的設計風格
吃 🍉 為主,隨筆撰寫
共享内存(Shared Memory) 允许多个进程可以访问同一块内存空间,这是效率最高的进程间通讯形式。
Shared Memory 之所以效率最高,主要是少了資料複製的成本,以 IPC 來說需要將訊息在 User Space 與 Kernel Space 之間複製傳輸,而使用 Shared Memory 只要將其映射到 process 所處的虛擬定址空間
圖片來源:Inter-Process Communication - Operating System Notes
针对那些比较抽象的场景,如果确实不好把 HTTP 方法映射为资源的所需操作,REST 也并不会刻板地要求一定要做映射。这时,用户可以使用自定义方法,按 Google 推荐的 REST API 风格来拓展 HTTP 标准方法。 自定义方法应该放在资源路径末尾,嵌入冒号加自定义动词的后缀。比如,我将删除操作映射到标准 DELETE 方法上,此外还要提供一个恢复删除的 API,那它可能会被设计为:
POST /user/user_id/cart/book_id:undelete
進度緩慢地吃瓜
RPC(Remote procedure call),是指位於互不重合的內存地址空間中的兩個程序,在語言層面上,以同步的方式使用頻寬有限的信道來傳輸程序控制訊息。
兩個進程之間交換數據稱之為進程間通信(Inter-Process Communication,IPC),方法有幾種:
|
操作符kill
指令其中前三種(Pipe、Signal、Semaphore)只適合傳遞少量訊息,Shared Memory 效率最高, Socket 則可用於不同機器之間的通信。
一直沒有能滿足“簡單”、“普適”、“高性能”三點的“完美 RPC 協議“,時至今日,整體也不再追求大而全的完美,而是以不同特點作為主要的發展方向:
兩者抽象的目標不一樣,REST 面向資源(Resource Oriented);RPC 面向過程(Procedure Oriented)。概念上也不同,REST 並非協議,只是風格。而在使用範圍上,兩者都屬於主流的遠程調用方式。
為“表徵狀態轉移”的縮寫(Representational State Transfer),實際上是“HTT”(Hypertext Transfer)的進一步抽象
HTTP 中使用的“超文本(Hypertext)”(或超媒體,Hypermedia)指的是一種能夠對操作進行分支判斷和差異響應的文本(或聲音、圖像)
- 資源(Resource):當瀏覽器向服務端發出請求,取得文章內容,這篇文章的內容本身稱之為”資源“
- 表徵(Representation):服務器向瀏覽器返回的 HTML 就是該資源的其中一種“表徵”,同一份資源可能有多種其他“表徵”(如 PDF)
- 狀態:使用者想看“下一篇文章”時,會需要傳遞”當前是在哪一份文章”的資訊給服務器,這類在特定語境中才能產生的上下文訊息稱之為“狀態”
- 轉移:服務器透果某種方式,將用戶當前閱讀的文章轉變成下一篇文章,稱之為“表徵狀態轉移”
- 統一接口:HTTP 協議中約定好七種基本操作,針對特定的 URI 採取這些操作,服務器就會觸發相應的表徵狀態轉移
- 超文本驅動:任何狀態轉移行為都不是預置於瀏覽器代碼中,而是由服務器發出的請求響應信息(超文本)來驅動
- 自描述消息:在給客戶端的訊息中,要明確告知客戶端消息的類型和應如何處理這段消息,例如於 Content-Type Header 中標示 MIME type
降低系統的網路性:某功能如果使用有狀態的設計只需少量的請求就能達成,使用無狀態會需要多次或攜帶冗余訊息的請求
- 分層系統:客戶端不需要知道是否直接連接到最終的服務器,或是路徑上中間的服務器。典型應用為 CDN。
- 統一接口:希望面向資源編程,而非面向服務。面向資源的抽象程度通常更高。
- 按需代碼
由低至高
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 和客戶端是完全解耦的 |
此處的“事務”指的是通過服務協議或架構,在分布式服務中獲得對多個數據同時提交的統一協調能力(2PC/2PC)
- 沒有傳輸可靠性支持*
- 缺乏對資源進行“部分”和“批量”的處理能力
在這之前從來沒覺得 RPC 和 REST 這兩個名詞/概念是可以被放在一起比較的,但這裡用了一個比較高階的視角看待兩者。RPC 和 REST 被創造出來,都有為了“呼叫或存取網路上其他服務器的資源”的目的(也就是本章的主題——訪問遠程服務),只是一個(RPC)基於面向過程,一個(REST)基於面向資源,後者又比前者更抽象,更遠離人類的直覺思考,也因此能更加通用。
RPC 相對 REST 的高效、接近電腦世界中主流的交互方式,較適合存在於服務器之間的溝通;而 REST 基於 HTTP 協議,奠基於應用層,符合網路世界的主流交互方式,較適合存在於服務器與客戶端之間的溝通。
存取遠端服務