天天看點

深入淺出RPC架構|青訓營筆記

課程資料

課程視訊:https://live.juejin.cn/4354/yc_RPC-framework

課程導學:https://juejin.cn/post/7099665398655615006/#heading-0

課後作業:https://juejin.cn/post/7099742161540743198/

由于課程涉及到的RPC知識需要自己對其有較為全面的了解後才能比較好的get到課程中提及的各種架構設計的點,是以我建議閱讀Kitex架構的源碼,再結合課程目錄去體會Kitex設計的初衷,筆記就以羅列概況為主,以備後續對比查閱。

基本概念

需要解決的問題

  • 函數映射
  • 資料轉換成位元組流
  • 網絡傳輸
深入淺出RPC架構|青訓營筆記

RPC的好處

  • 單一職責,有利于分工協作和運維開發
  • 可擴充性強
  • 故障隔離,服務整體更可靠

使用RPC的問題

  • 服務當機,對方如何處理?
  • 調用時發生網絡異常,如何保證消息的可達性?
  • 請求量突增導緻服務無法及時處理,有哪些應對措施?

分層設計

深入淺出RPC架構|青訓營筆記

編解碼層

  • 語言特定的格式:一些語言内建了将記憶體對象編碼為位元組序列的支援,如Java的java.io.Serializable
  • 文本格式:JSON、XML、CSV,具有可讀性
  • 二進制編碼:具有跨語言,高性能優點,如Thrift的BinaryProtocol、Protobuf等

協定層

  • 特殊結束符:一個特殊字元作為每個協定單元結束标志
深入淺出RPC架構|青訓營筆記
  • 變長協定:定長加不定長的部分組成,其中定長的部分需要描述不定長内容長度
深入淺出RPC架構|青訓營筆記

網絡通信層

深入淺出RPC架構|青訓營筆記

關鍵名額

穩定性&易用性&擴充性

  • 熔斷:保護調用方,防止被調用的服務出現問題而影響整個鍊路
  • 限流:保護被調用方,防止大流量把服務壓垮
  • 逾時控制:避免浪費資源在不可用的節點上
  • 請求成功率
    • 負載均衡
    • 重試
  • 長尾請求
    • 網絡抖動
    • GC
    • Backup Request(解決方式)
  • 注冊中間件:以上的功能都通過注冊中間件的方式啟用

觀測性

  • Log(日志)、Metric(監控)、Tracing(追蹤)
  • 内置觀測性服務

高性能

  • 高吞吐
  • 低延遲
  • 手段:
    • 連接配接池
    • 多路複用
    • 高性能編解碼協定
    • 高性能網絡庫

企業實踐

Kitex是位元組跳動内部的Golang微服務RPC架構,先已開源。

Kitex文檔:https://www.cloudwego.io/zh/docs/kitex/getting-started/

Kitex體驗:https://juejin.cn/post/7098966260502921230

Kitex源碼閱讀—腳手架代碼的生成(一):https://juejin.cn/post/7100867939829563422

整體架構

深入淺出RPC架構|青訓營筆記

自研網絡庫

原生網絡庫的問題

  • 原生庫無法感覺連接配接狀态

在使用連接配接池時,池中存在失效的連接配接,影響連接配接池的複用。

  • 原生庫存在goroutine暴漲的風險

一個連接配接一個goroutine的模式,由于連接配接使用率低下,存在大量goroutine占用排程開銷,影響性能。

自研網絡庫 — Netpoll

  • 解決無法感覺連接配接狀态

引入epoll主動監聽機制,感覺連接配接狀态

  • 解決goroutine暴漲的風險

建立goroutine池,複用goroutine

  • 提升性能

引入Nocopy Buffer,向上層提供NoCopy 的調用接口,編解碼層面零拷貝

擴充性設計

支援多協定,也支援靈活的自定義協定擴充

深入淺出RPC架構|青訓營筆記

性能優化

網絡庫優化

  • 排程優化
    • epoll_wait在排程上的控制
    • gopool重用goroutine,降低同時運作攜程數
  • LinkBuffer
    • 讀寫并行無鎖,支援nocopy地流式讀寫
    • 高效擴縮容
    • Nocopy Buffer池化,減少GC
  • Pool
    • 引入記憶體池和對象池,減少GC開銷

編解碼優化

  • Codegen
    • 預計算并配置設定記憶體,減少記憶體操作次數,包括記憶體配置設定和拷貝
    • inline減少函數調用次數和避免不必要的反射操作
    • 自研了Go語言實作的Thrift IDL解析和代碼生成器,支援完善的Thrift IDL文法和語義檢查,并支援了插件機制 — Thriftgo
  • JIT
    • 使用JIT編譯技術改善使用者體驗的同時帶來更強的編解碼性能,減輕使用者維護生成代碼的負擔
    • 基于JIT編譯技術的高性能動态Thrift 編解碼器 — Frugal

合并部署

  • 微服務過于微小,傳輸和序列化開銷越來越大
  • 将親和性強的服務執行個體盡可能排程到同一個實體機,遠端RPC調用優化為本地IPC調用

小結

由于課程關于RPC架構的了解需要結合具體的使用經驗,是以我推薦嘗試開始獨立閱讀Kitex的源碼,可以從邊緣元件開始,如:分析是如何通過指令行建立腳手架代碼的,等逐漸熟悉源碼分析的方法之後,可以嘗試閱讀核心元件的源碼,再結合課程的組織目錄,仔細體會Kitex的設計。