微服務一直以來是服務治理的基本盤之一,落地到云原生上,往往是每個 K8s pods 部署一個服務,獨立迭代、獨立運維。
但是在快速部署的時候,有時候,我們可能需要一些宏服務的優勢。有沒有一種方法,能夠 “既要又要” 呢?本文基于 tRPC-Go 服務,提出并最終實踐了一種經驗證可行的方法。
一、微服務的優劣
微服務是云原生的大潮流,它的優勢非常明顯:
-
微服務大大降低了模塊間的耦合。當某個模塊 / 微服務需要變更時,只需要調整這個微服務即可,其他服務無感知;
-
微服務化使得模塊的更新能夠平滑過渡,避免了停機更新的問題,也適合大型團隊或多個團隊間合作構建;
-
微服務模塊的輸入 / 輸出定義很明確,非常適合融合 DDD 理念進行設計;
-
問題排查時,能夠快速定位出現問題的模塊,對運維也很友好。
然而微服務也存在劣勢:
-
當系統趨向復雜時,隨著微服務的拆分、功能的繁雜和細化,微服務越來越多,一窺系統全貌的難度越來越大;
-
模塊間通信通過 RPC 實現,RPC 帶來了時間和網絡流量的開銷;
-
依賴于完備的服務治理體系,對小團隊而言,部署成本較高;
-
多租戶隔離部署時,運維難度也成倍增加。
二、遇到的問題
我們是心悅俱樂部首頁 Feeds 流推薦系統的開發團隊。但我們推薦系統也接入了其他業務,比如我們在接入游戲知幾項目的一個功能后,全量發布前的壓測中發現 CPU 開銷大到難以接受。
1.分析
我們的系統是簡單按照 “業務 → 分流 → 重排 → 精排 → 召回” 的推薦系統微服務化部署,沒有做編排化:
觀察壓測數據,我們會發現,在分流層前后的服務,網絡開銷非常大:
分流服務是推薦系統的總入口,它沒有很強的業務屬性,而是在整個推薦系統的前面、在業務數據的基礎上,加入 A/B Test 參數,供整個推薦系統使用。所以它對于業務負載基本是透傳的。
很明顯,業務服務發給推薦系統的數據流量非常大,而作為透明傳輸業務數據的分流服務,入參需要反序列化,出參需要重新序列化,這些都是無謂的算力消耗。
三、解決方案
從代碼上看,占流量大頭的數據結構,在整個調用鏈路上都是一致的,我們自然想到&#x