文章出處

Redola.Rpc 的一個小目標

Redola.Rpc 的一個小目標:20000 tps

   Concurrency level: 8 threads
   Complete requests: 20000
Time taken for tests: 0.886 seconds
    Time per request: 0.044 ms (avg)
 Requests per second: 22573 [#/sec] (avg)
   Concurrency level: 8 threads
   Complete requests: 10000
Time taken for tests: 0.424 seconds
    Time per request: 0.042 ms (mean)
 Requests per second: 23584 [#/sec] (avg)

測試環境使用 AWS 虛擬機 AWS EC2 C4 Instance Model c4.2xlarge,配置如下:

Processor: Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz
     vCPU: 8
   Memory: 15 GiB
  Storage: 30G EBS-Only
Bandwidth: 1,000 Mbps
       OS: Windows Server 2012 R2

Redola.Rpc 是什么?

  • Redola.Rpc 是一個基于 C# 的輕量級 RPC 框架;
  • Redola.Rpc 是一個源代碼托管在 GitHub 上的開源項目;
  • Redola.Rpc 是一個發布在 nuget.org 上的可安裝軟件包;

  源代碼開源地址:https://github.com/gaochundong/Redola

  樣例測試代碼:https://github.com/gaochundong/Redola/tree/master/Tests

Redola.Rpc 的特點

  • 簡單粗暴,一看就懂;
  • 簡單的注冊中心,消除配置障礙;
  • 支持 Request / Response 阻塞模型;
  • 支持任意服務間的消息推送;
  • 內置 protobuf 序列化,提供可替換接口;

Redola.Rpc 內部結構

Redola.Rpc 基于 Cowboy.Sockets 進行構建,使用 TCP Socket 進行服務間通信,默認使用 .NET APM TCP Socket 模式。通過 Actor 模型抽象封裝 Socket 連接與交互,實現 Actor 之間的 Register、Lookup、Handshake、KeepAlive 等功能;

Redola.Rpc 概念模型

  • Actor Peer:代表一個 Actor 節點,任意 Actor 之間均可通信;
  • Actor Master:作為 Actor 節點注冊中心,用于服務的注冊與發現;
  • Actor Identity:一個 Actor 的身份描述,包括 Type、Name、Address、Port 等;
  • RPC Service:用于實現具體的 RPC 服務,一個 Actor 可以注冊多個 RPC Service;

Redola.Rpc 通信模型

Actor Peer 與 Actor Peer 之間通過 TCP 長連接進行通信。Actor 封裝了 TCP 中關于 TcpClient 和 TcpServer 的抽象,對外不再暴露 Client 和 Server 的概念,僅以 Peer 呈現,Peer 與 Peer 之間是平等的。Actor Master 與其他 Peer 的區別僅是承擔了 Register 和 Lookup 的職責。

Actor Peer 間通過 Actor Master 查詢到需要通信的對端 Actor Peer 的 Actor Identity,會首先進行 Handshake 交換 Actor Identity,用以記錄對方的身份。Handshake 之后,即可進行預定義注冊的 RPC 消息通信。

為掌握對端 Peer 的活躍情況,通過內置的 KeepAlive 機制進行服務間保活,每隔約定時間進行消息交互,若超時時間內未獲得保活回復,則自動斷開連接。KeepAlive 同時做了一定的優化,若服務間在保活時間內有任何 Send 或 Receive 消息操作,則視為有服務間通信,即對端為活躍狀態,會延遲發送保活請求。

假設 Actor 1 (Tyep:hello, Name:hello-001, Address:192.168.1.139, Port:8888) 需要與 Actor 2 (Type:world, Name:world-001, Address:192.168.1.158, Port:7777) 進行通信,則僅需發送消息時指定 Actor 2 的身份 (world, world-001),其中 world 為 Actor 2 的類型,world-001 為該 world 類型下名稱為 world-001 的 Actor Peer。

Redola.Rpc 基本契約

  • 任意 Actor 均需向 Actor Master 注冊,提供自身 Actor Identity 信息;
  • 僅指定 Actor Type 發送消息,則會隨機 Lookup 一個該 Type 的 Actor 進行通信;
  • Actor 不區分 Client 和 Server 角色,角色由使用者設計;
  • RPC 調用接口有同步和異步之分,由使用者選擇;
  • 支持 Request/Response 同步阻塞模式,可設置阻塞超時時間;
  • 消息注冊后,通過反射匹配消息處理方法,On + MessageType 契約編程;
  • RPC 限流在消息處理側實施,默認 RateLimiter 限制 CPU 相同數量線程;
  • 內部 TCP 配置 Buffer Pool 連續內存會伴隨連接數和吞吐增加,單 Buffer 8K 大小;
  • 若 RPC 傳遞消息大于 84K,.NET 將 Buffer 分配到 LOH 上,GC 未必及時回收;

Redola.Rpc 的依賴庫

有那么多 RPC 框架,為什么要自己寫一個?

演進出來的,那就是一個故事了。

起初,我們作為一個初創公司,還在嘗試思考清楚我們要做的東西究竟應該是什么樣子,畢竟市場上少有同類競品,那么首先設計一個原型是合理的。所以,我們只有一個應用程序,用于定時拉取第三方合作伙伴的 WebService 數據,并通過設計的算法進行計算處理,然后寫入數據庫;

有了數據,總要找地方展現吧,于是招聘了 Unity3D 前端開始做炫酷的 App,有實時數據推送的展現要求,所以前后端通信使用了 WebSocket 協議,也就產生了 Cowboy.WebSockets;

第三方合作伙伴的 WebService 顯然不只一個接口,多個接口并發拉取,每 100 毫秒拉取一次,線程繁忙影響了計算處理和寫入數據庫;好,將數據拉取分離出去,并進行前期的數據清洗和過濾,然后再發給算法計算引擎;這時,就有了 2 個服務,一個負責拉取數據 Feed,一個負責計算入庫 Engine,通過 Cowboy.Sockets 進行 TCP 消息通信;

終于有更多的數據可供展現了,當然 U3D App 也快開發完成了,App 不可能就裝在一個手機上吧,萬一發布到 AppStore 上火了呢?引入了接入層 Gateway 系列服務,用于保持 WebSocket 長連接和數據推送;好,現在有了 2 + n 個服務了,并且 n > 5 還做了軟負載均衡;

算法引擎 Engine 計算完后,要將數據分發到這 n 個 Gateway 服務上,臣妾就這兩顆 CPU,著實做不到啊!分發成了瓶頸,萬一 n 成長到 50 怎么辦?好,將數據推送委托給新服務 Bolt 服務,專門做推送給 Gateway;

引擎算法發現需要更多輸入源數據參與計算,好吧,引入更多第三方數據 Feed 提供商,每家一個服務做拉取;艾瑪~ 每家實際上是多個服務拉取~ 還有要求主動推送的 ~

哎呀,對于同一領域對象,每家的描述 ID 顯然不一樣,畢竟不是一個公司,手工匹配好煩,眼睛都快瞎了,做個 Mapping 自動服務根據特征專門負責匹配 ID,匹配好了再發給引擎,媽媽再也不用擔心我的 ID;

數據簡直不要太多,計算引擎 Engine 邊計算邊入庫,常年 100% CPU 啊我的哥;拆!先將預處理數據入庫,再將計算的結果入庫;

什么?數據庫寫入有延遲?線程被阻塞,又跟我的 CPU 過不去!拆,引流寫操作到 MQ 消息隊列,加上 Durability 落地,愛阻塞誰阻塞誰,愛啥時候寫啥時候寫。

隔壁老王看了一眼我們的 U3D App,矮油不錯哦,狂拽酷霸吊炸天啊!你們這數據算法和計算引擎有些超出我的知識范圍,我有一些新的產品想法,要么你們幫我實現 H5,要么你們提供 API 我們自己實現 H5,反正我的想法必須實現,你看這是 20% 預付款你們下個星期能不能上線 API 啊?王哥,有錢還能有辦不成的事兒?是吧,說,你都要啥推送接口?Socket + Protobuf 可以吧?HTTP 也行?

剛回國的尼古拉斯趙四聽聞有 API 開放能力,那必須接入啊,共享經濟實現共贏嘛,有錢大家一起賺,只是這 API 接口能不能修改成 RESTful + 反向 POST?

我相信,明天還會有新需求的!要善待今天的自己,底層封裝成 Redola.Rpc 框架!

 

版權聲明:本篇文章《Redola.Rpc 的一個小目標》由作者 Dennis Gao 發表自博客園個人技術博客,未經作者本人同意禁止以任何的形式轉載,任何自動的或人為的爬蟲轉載行為均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()