RPC 實戰與原理 精簡版

什麼是 RPC?

Remote Procedure Call,遠程過程調用。

RPC 有什麼作用?

  • 屏蔽遠程調用、本地調用的區別
  • 隱藏底層網絡通信的複雜性,讓我們更專注於業務

RPC 步驟

爲什麼需要序列化?

  • 網絡傳輸必須是「二進制」,調用方的參數都是對象
  • 請求↔二進制消息體

零拷貝

什麼是零拷貝?

爲什麼需要零拷貝?

網卡等操作,只能通過內核操作應用程序要發送網絡數據,需要將數據複製到內核

如何實現零拷貝?

虛擬內存

  • mmap + write
  • sendfile

Netty 的零拷貝有何不同?

  • 一個請求,可能拆分成多個數據包
  • 數據包的組合在用戶空間,解決用戶空間內存的拷貝處理問題,CompositeByteBuf
  • 也包括用戶空間、內核空間的數據拷貝:Direct Buffers

動態代理實現

  • JDK:只能代理接口
  • Javassist操作底層字節碼,不需要反射,性能好
  • Byte Buddy:更容易的 API,速度比 Javassist 快,Spring、Jackson 使用

HTTP/2 特性

  • 多路複用,同一鏈路雙向發送stream數據
  • Header 壓縮

爲什麼需要服務發現?

公共的“通訊錄”

爲什麼不用 DNS?

  • DNS多級緩存,且緩存時間長
  • 需要搭建負載均衡,額外成本

定時任務 & 時間輪

定時任務的問題?

  • future 啓動線程進行異步編程,sleep
  • 如果5秒超時,高併發的
  • 讓CPU額外輪詢遍歷,浪費CPU

時間輪的應用

  • 延遲消息
  • 訂單過期(10分鐘未付款,取消訂單)

時鐘輪本質

減少額外的掃描操作

時間輪在 RPC 的應用

調用端請求的超時處理,節省CPU

時間輪實現

Netty的 TimeWheel

如何註冊和發現服務?

  • RPC Server 提供服務,向 Registry 註冊自身
  • RPC Client 調用服務,從 Registry 拉取服務列表
  • Server 節點變更時,同步變更,Client 感知刷新本地的「服務節點列表」

實現:

  • 註冊中心 API
  • 服務健康狀態監測:ZooKeeper 的會話超時控制機制
  • 服務狀態變更通知:ZooKeeper 的 Watcher 機制

如何實現 RPC 遠程調用?

  • 客戶端、服務端如何建立網絡連接:HTTP、Socket
  • 服務端如何處理請求:NIO(使用 Netty
  • 數據傳輸採用什麼協議
  • 數據如何序列化、反序列化:JSON,PB,Thrift

如何追蹤微服務?

核心理念:調用鏈,全局唯一的 ID 將同一請求串聯起來,從而還原調用關係,統計系統指標。

註冊中心選型

  • 高可用
    • 集羣部署:多個實例
    • 多機房部署:一個機房斷電等不可抗因素
  • 數據一致性
    • CP 型:ZooKeeper(Redis),強一致性,機房間斷網,註冊中心不可用
    • AP 型:犧牲一致性,保證可用性。Eureka

開源 RPC 框架

限定語言

  • Dubbo:Java,阿里
  • Motan:Java,微博
  • Tars:C++,騰訊(已支持多語言)
  • Spring Cloud:Java
    • 網關 Zuul
    • 註冊中心 Eureka
    • 服務超時熔斷 Hystrix
    • 調用鏈監控 Sleuth
    • 日誌分析 ELK

跨語言 RPC 框架

  • gRPC:HTTP/2
  • Thrift:TCP

Spring Cloud 微服務架構

代碼、思維導圖筆記鏈接

代碼和思維導圖在 GitHub 項目中,歡迎大家 star!

coding 筆記、點滴記錄,以後的文章也會同步到公衆號(Coding Insight)中,希望大家關注_

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章