課程資料
課程視訊: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的問題
- 服務當機,對方如何處理?
- 調用時發生網絡異常,如何保證消息的可達性?
- 請求量突增導緻服務無法及時處理,有哪些應對措施?
分層設計
編解碼層
- 語言特定的格式:一些語言内建了将記憶體對象編碼為位元組序列的支援,如Java的java.io.Serializable
- 文本格式:JSON、XML、CSV,具有可讀性
- 二進制編碼:具有跨語言,高性能優點,如Thrift的BinaryProtocol、Protobuf等
協定層
- 特殊結束符:一個特殊字元作為每個協定單元結束标志
- 變長協定:定長加不定長的部分組成,其中定長的部分需要描述不定長内容長度
網絡通信層
關鍵名額
穩定性&易用性&擴充性
- 熔斷:保護調用方,防止被調用的服務出現問題而影響整個鍊路
- 限流:保護被調用方,防止大流量把服務壓垮
- 逾時控制:避免浪費資源在不可用的節點上
- 請求成功率
- 負載均衡
- 重試
- 長尾請求
- 網絡抖動
- 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
整體架構
自研網絡庫
原生網絡庫的問題
- 原生庫無法感覺連接配接狀态
在使用連接配接池時,池中存在失效的連接配接,影響連接配接池的複用。
- 原生庫存在goroutine暴漲的風險
一個連接配接一個goroutine的模式,由于連接配接使用率低下,存在大量goroutine占用排程開銷,影響性能。
自研網絡庫 — Netpoll
- 解決無法感覺連接配接狀态
引入epoll主動監聽機制,感覺連接配接狀态
- 解決goroutine暴漲的風險
建立goroutine池,複用goroutine
- 提升性能
引入Nocopy Buffer,向上層提供NoCopy 的調用接口,編解碼層面零拷貝
擴充性設計
支援多協定,也支援靈活的自定義協定擴充
性能優化
網絡庫優化
- 排程優化
- 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的設計。