十萬同時在線用戶,需要多少內存?——Newbe.Claptrap 框架水平擴展實驗

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Newbe.Claptrap 項目是筆者正在構建以"},{"type":"codeinline","content":[{"type":"text","text":"反應式"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"Actor模式"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"事件溯源"}]},{"type":"text","text":"爲理論基礎的一套服務端開發框架。本篇我們將來了解一下框架在水平擴展方面的能力。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前情提要"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"時隔許久,今日我們再次見面。首先介紹一下過往的項目情況:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/Overview-Of-Newbe-Claptrap/","title":null},"content":[{"type":"text","text":"第一次接觸本框架的讀者,可以先點擊此處閱讀本框架相關的基礎理論和工作原理。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"日前,我們也編寫了一些預熱文章和工具,讀者可以通過以下鏈接進行了解:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/Reactive-In-Server-1/","title":null},"content":[{"type":"text","text":"談反應式編程在服務端中的應用,數據庫操作優化,從 20 秒到 0.5 秒"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Others/Full-Speed-To-Download-Netcore-Docker-Images/","title":null},"content":[{"type":"text","text":"docker-mcr 助您全速下載 dotnet 鏡像"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/Newbe-Claptrap-Weekly-1/","title":null},"content":[{"type":"text","text":"Newbe.Claptrap 項目週報 1 - 還沒輪影,先用輪跑"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"今日主題"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"今天,我們來做一套實驗預演,來驗證 Newbe.Claptrap 框架,如何通過水平擴展的形式來適應逐漸增長的同時在線用戶數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於此次實驗涉及的內容很多,因此筆者將內容進行了歸類,讀者可以按照自己的興趣閱讀相關的章節:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/#業務需求說明","title":null},"content":[{"type":"text","text":"業務需求說明"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/#調用時序關係","title":null},"content":[{"type":"text","text":"調用時序關係"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/#物理結構設計","title":null},"content":[{"type":"text","text":"物理結構設計"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/#實際測試數據","title":null},"content":[{"type":"text","text":"實際測試數據"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/#源碼構建說明","title":null},"content":[{"type":"text","text":"源碼構建說明"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/#常見問題解答","title":null},"content":[{"type":"text","text":"常見問題解答"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"業務需求說明"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"先看看今天要實現的業務場景:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶通過 API 登錄後生成一個 JWT token"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶調用 API 時驗證 JWT token 的有效性"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒有使用常規的 JWS 公私鑰方式進行 JWT token 頒發,而是爲每個用戶單獨使用 secret 進行哈希驗證"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"驗證看不同的在線用戶需要消耗的內存情況"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶登錄到生成 token 所消耗時間不得超過 200 ms"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"tokn 的驗證耗時不得超過 10 ms"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"吹牛先打草稿"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"筆者沒有搜索到於 “在線用戶數” 直接相關的理論定義,因此,爲了避免各位的理解存在差異。筆者先按照自己的理解來點明:在線用戶數到底意味着什麼樣的技術要求?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"未在線用戶若上線,不應該受到已在線用戶數的影響"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果一個用戶登錄上線需要消耗 100 ms。那麼不論當前在線的用戶數是十人還是百萬人。這個登錄上線所消耗的時間都不會明顯的超過 100 ms。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,有限的物理硬件肯定會使得,當在線用戶數超過一個閾值(例如兩百萬)時,新用戶登錄上線會變慢甚至出錯。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,增加物理機器就能提高這個閾值,我們就可以認爲水平擴展設計是成功的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"對於任意一個已在線用戶,得到的系統性能反饋應當相同"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如已在線的用戶查詢自己的訂單詳情,需要消耗 100 ms。那麼當前任何一個用戶進行訂單查詢的平均消耗都應該穩定在 100 ms。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,這裏需要排除類似於 “搶購” 這種高集中性能問題。此處主要還是討論日常穩定的容量增加。(我們以後會另外討論 “搶購” 這種問題)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具體一點可以這樣理解。假設我們做的是一個雲筆記產品。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼,如果增加物理機器就能增加同時使用雲筆記產品的用戶數,而且不犧牲任何一個用戶的性能體驗,我們就認爲水平擴展設計是成功的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在此次的實驗中,若用戶已經登錄,則驗證 JWT 有效性的時長大約爲 0.5 ms。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"調用時序關係"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c5/c5275fe97967395c2efa4398c0f4503c.png","alt":"Timing diagram","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"簡要說明:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"客戶端發起登錄請求將會逐層傳達到 UserGrain 中"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"UserGrain 將會在內部激活一個 Claptrap 來進行維持 UserGrain 中的狀態數據。包括用戶名、密碼和用於 JWT 簽名的 Secret。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"隨後的生成 JWT 生成和驗證都將直接使用 UserGrain 中的數據。由於 UserGrain 中的數據是在一段時間內是 “緩存” 在內存中的。所以之後的 JWT 生成和驗證將非常快速。實測約爲 0.5 ms。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"物理結構設計"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2d/2de360a7777693f9ab2768abc86b30c4.png","alt":"物理結構設計","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如上圖所示,便是此次進行測試的物理組件:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"名稱說明WebAPI公開給外部調用 WebAPI 接口。提供登錄和驗證 token 的接口。Orleans Cluster託管 Grain 的核心進程.Orleans Gateway於 Orleans Cluster 基本相同,但是 WebAPI 只能與 Gateway 進行通信Orleans Dashboard於 Orleans Gateway 基本相同,但增加了 Dashboard 的展示,以查看整個 Orleans 集羣的情況Consul用於 Orleans 集羣的集羣發現和維護Claptrap DB用於保存 Newbe.Claptrap 框架的事件和狀態數據Influx DB & Grafana用於監控 Newbe.Claptrap 相關的性能指標數據"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此次實驗的 Orleans 集羣節點的數量實際上是 Cluster + Gateway + Dashboard 的總數。以上的劃分實際上是由於功能設定的不同而進行的區分。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此次測試 “水平擴展” 特性的物理節點主要是 Orleans Cluster 和 Orleans Gateway 兩個部分。將會分別測試以下這些情況的內存使用情況。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Orleans DashboardOrleans GatewayOrleans Cluster100111135"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此次實驗採用的是 Windows Docker Desktop 結合 WSL 2 進行的部署測試。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上的物理結構實際上是按照最爲此次實驗最爲複雜的情況設計的。實際上,如果業務場景足夠簡單,該物理結構可以進行裁剪。詳細可以查看下文 “常見問題解答” 中的說明。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"實際測試數據"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以下,分別對不同的集羣規模和用戶數量進行測試"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"0 Gateway 0 Cluster"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認情況下,剛剛啓動 Dashboard 節點時,通過 portainer 可以查看 container 佔用的內存約爲 200 MB 左右,如下圖所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fa/fa60699c21cee4d1e665982081c1cfc8.png","alt":"初始內存佔用","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過測試控制檯,向 WebAPI 發出 30,000 次請求。每批 100 個請求,分批發送。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"經過約兩分鐘的等待後,再次查看內存情況,約爲 9.2 GB,如下圖所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1c/1cb116edae9f332a575c5498f04106c7.png","alt":"三萬用戶","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,我們簡單的估算每個在線用戶需要消耗的內存情況約爲 (9.2*1024-200)/30000 = 0.3 MB。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外,可以查看一些輔助數據:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CPU 使用情況"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ff/ffbe2da3475c36bb0c187fbf4dc6f1ef.png","alt":"CPU使用情況","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"網絡吞吐量"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f6/f67f7ff3041ae67f974d4fe91124238c.png","alt":"網絡吞吐量","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Orleans Dashboard 情況。左上角的 TOTAL ACTIVATIONS 中 30,000 即表示當前內存中存在的 UserGrain 數量,另外的 3 個爲 Dashboard 使用的 Grain。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/20/207d5ae371e861abcf0debe80b1dc90b.png","alt":"Orleans Dashboard 情況","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Grafana 中查看 Newbe.Claptrap 的事件平均處理時長約爲 100-600 ms。此次測試的主要是內存情況,處理時長的採集時間爲 30s 一次,因此樣本數並不多。關於處理時長我們將在後續的文章中進行詳細測試。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8d/8dbb09fc13fc148c7d04a71806d84bee.png","alt":"時間平均處理時長","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Grafana 中查看 Newbe.Claptrap 的事件的保存花費的平均時長約爲 50-200 ms。事件的保存時長是事件處理的主要部分。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/93/93813be7e521efb96a3fc1184c4e45ba.png","alt":"三萬用戶","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Grafana 中查看 Newbe.Claptrap 的事件已處理總數。一種登錄了三萬次,因此事件總數也是三萬。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d3/d36e5f48ab9df5e7ed45049c1cad4548.png","alt":"事件處理的總數","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1 Gateway 1 Cluster"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來,我們測試額外增加兩個節點進行測試。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"還是再提一下,Orleans 集羣節點的數量實際上是 Cluster + Gateway + Dashboard 的總數。因此,對比上一個測試,該測試的節點數爲 3。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"測試得到的內存使用情況如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶數節點平均內存內存總佔用100001.8 GB1.8*3 = 5.4 GB200003.3 GB3.3*3 = 9.9 GB300004.9 GB4.9*3 = 14.7 GB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼,以三萬用戶爲例,平均每個用戶佔用的內存約爲 (14.7*1024-200*3)/30000 = 0.48 MB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲什麼節點數增加了,平均消耗內存上升了呢?筆者推測,沒有進行過驗證:節點增加,實際上節點之間的通訊還需要消耗額外的內存,因此平均來說有所增加。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3 Gateway 5 Cluster"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們再次增加節點。總結點數爲 1 (dashboard) + 3 (cluster) + 5 (gateway) = 9 節點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"測試得到的內存使用情況如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶數節點平均內存內存總佔用200001.6 GB3.3*9 = 14.4 GB300002 GB4.9*9 = 18 GB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼,以三萬用戶爲例,平均每個用戶佔用的內存約爲 (18*1024-200*9)/30000 = 0.55 MB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"十萬用戶究竟要多少內存?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上所有的測試都是以三萬爲用戶數進行的測試,這是一個特殊的數字。因爲繼續增加用戶數的話,內存將會超出測試機的內存餘量。(求贊助兩條 16G)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果繼續增加用戶數,將會開始使用操作系統的虛擬內存。雖然可以運行,但是運行效率會降低。原來登錄可能只需要 100 ms。使用到虛擬內存的用戶則需要 2 s。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,速度降低的情況下,在驗證需要多少內存意義可能不大。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,這不意味着不能夠繼續登錄,以下便是 1+1+1 的情況下,十萬用戶全部登錄後的情況。(有十萬用戶同時在線,加點內存吧,不差錢了。)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a1/a1b79458d84072f24f7f73a9fb9a6de4.png","alt":"十萬用戶","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"源碼構建說明"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此次測試的代碼均可以在文末的樣例代碼庫中找到。爲了方便讀者自行實驗,主要採用的是 docker-compose 進行構建和部署。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此對於測試機的唯一環境需求就是要正確的安裝好 Docker Desktop 。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以從以下任一地址獲取最新的樣例代碼:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://github.com/newbe36524/Newbe.Claptrap.Examples","title":null},"content":[{"type":"text","text":"https://github.com/newbe36524/Newbe.Claptrap.Examples"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://gitee.com/yks/Newbe.Claptrap.Examples","title":null},"content":[{"type":"text","text":"https://gitee.com/yks/Newbe.Claptrap.Examples"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"快速啓動"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用控制檯進入 "},{"type":"codeinline","content":[{"type":"text","text":"src/Newbe.Claptrap.Auth/LocalCluster"}]},{"type":"text","text":" 文件夾。運行以下命令便可以在本地啓動所有的組件:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"docker-compose up -d"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"途中需要拉取一些託管於 Dockerhub 上的公共鏡像,請確保本地已經正確配置了相關的加速器,以便您可以快速構建。"},{"type":"link","attrs":{"href":"https://www.runoob.com/docker/docker-mirror-acceleration.html","title":null},"content":[{"type":"text","text":"可以參看這篇文檔進行設置"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"成功啓動之後可以通過 "},{"type":"codeinline","content":[{"type":"text","text":"docker ps"}]},{"type":"text","text":" 查看到所有的組件。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"PS>docker ps\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n66470e5393e2 registry.cn-hangzhou.aliyuncs.com/newbe36524/newbe-claptrap-auth-webapi \"dotnet Newbe.Claptr…\" 4 hours ago Up About an hour 0.0.0.0:10080->80/tcp localcluster_webapi_1\n3bbaf5538ab9 registry.cn-hangzhou.aliyuncs.com/newbe36524/newbe-claptrap-auth-backendserver \"dotnet Newbe.Claptr…\" 4 hours ago Up About an hour 80/tcp, 443/tcp, 0.0.0.0:19000->9000/tcp, 0.0.0.0:32785->11111/tcp, 0.0.0.0:32784->30000/tcp localcluster_dashboard_1\n3f60f51e4641 registry.cn-hangzhou.aliyuncs.com/newbe36524/newbe-claptrap-auth-backendserver \"dotnet Newbe.Claptr…\" 4 hours ago Up About an hour 80/tcp, 443/tcp, 9000/tcp, 0.0.0.0:32787->11111/tcp, 0.0.0.0:32786->30000/tcp localcluster_cluster_gateway_1\n7d516ada2b26 registry.cn-hangzhou.aliyuncs.com/newbe36524/newbe-claptrap-auth-backendserver \"dotnet Newbe.Claptr…\" 4 hours ago Up About an hour 80/tcp, 443/tcp, 9000/tcp, 30000/tcp, 0.0.0.0:32788->11111/tcp localcluster_cluster_core_1\nfc89fcd973f9 grafana/grafana \"/run.sh\" 4 hours ago Up 6 seconds 0.0.0.0:23000->3000/tcp localcluster_grafana_1\n1f10ed0eb25f postgres \"docker-entrypoint.s…\" 4 hours ago Up About an hour 0.0.0.0:32772->5432/tcp localcluster_claptrap_db_1\nd5d2bec74311 adminer \"entrypoint.sh docke…\" 4 hours ago Up About an hour 0.0.0.0:58080->8080/tcp localcluster_adminer_1\n4c4be69f2f41 bitnami/consul \"/opt/bitnami/script…\" 4 hours ago Up About an hour 8300-8301/tcp, 8500/tcp, 8301/udp, 8600/tcp, 8600/udp localcluster_consulnode3_1\n88811d3aa0d2 influxdb \"/entrypoint.sh infl…\" 4 hours ago Up 6 seconds 0.0.0.0:29086->8086/tcp localcluster_influxdb_1\nd31c73b62a47 bitnami/consul \"/opt/bitnami/script…\" 4 hours ago Up About an hour 8300-8301/tcp, 8500/tcp, 8301/udp, 8600/tcp, 8600/udp localcluster_consulnode2_1\n72d4273eba2c bitnami/consul \"/opt/bitnami/script…\" 4 hours ago Up About an hour 0.0.0.0:8300-8301->8300-8301/tcp, 0.0.0.0:8500->8500/tcp, 0.0.0.0:8301->8301/udp, 0.0.0.0:8600->8600/tcp, 0.0.0.0:8600->8600/udp localcluster_consulnode1_1"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"啓動完成之後,便可以通過以下鏈接來查看相關的界面"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"地址說明"},{"type":"link","attrs":{"href":"http://localhost:19000/","title":null},"content":[{"type":"text","text":"http://localhost:19000"}]},{"type":"text","text":"Orleans Dashboard 查看 Orleans 集羣中各節點的狀態"},{"type":"link","attrs":{"href":"http://localhost:10080/","title":null},"content":[{"type":"text","text":"http://localhost:10080"}]},{"type":"text","text":"Web API 基地址,此次使用所測試的 API 基地址"},{"type":"link","attrs":{"href":"http://localhost:23000/","title":null},"content":[{"type":"text","text":"http://localhost:23000"}]},{"type":"text","text":"Grafana 地址,查看 Newbe.Claptrap 相關的性能指標情況"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"源碼構建"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用控制檯進入 "},{"type":"codeinline","content":[{"type":"text","text":"src/Newbe.Claptrap.Auth"}]},{"type":"text","text":" 文件夾。運行以下命令便可以在本地完成代碼的構建:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"./LocalCluster/pullimage.cmd\ndocker-compose build"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"pullimage.cmd 使用了筆者編寫的 docker-mcr 加速器功能。"},{"type":"link","attrs":{"href":"https://www.newbe.pro/Others/Full-Speed-To-Download-Netcore-Docker-Images/","title":null},"content":[{"type":"text","text":"您可以通過該文檔來了解其工作原理"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"等待構建完畢之後,本地便生成好了相關的鏡像。接下來便可以初次嘗試在本地啓動應用:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用控制檯進入 "},{"type":"codeinline","content":[{"type":"text","text":"src/Newbe.Claptrap.Auth/LocalCluster"}]},{"type":"text","text":" 文件夾。運行以下命令便可以啓動相關的容器:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"docker-compose up -d"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"常見問題解答"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"文中爲何沒有說明代碼和配置的細節?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要爲讀者展示該方案的實驗可行性,具體應該如何應用 Newbe.Claptrap 框架編寫代碼,並非本文的主旨,因此沒有提及。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,另外一點就是目前框架沒有最終定版,所有內容都有可能發生變化,講解代碼細節意義不大。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但可以提前說明的是:編寫非常簡單,由於本樣例的業務需求非常簡單,因此代碼內容也不多。全部都可以在示例倉庫中找到。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"用 Redis 存儲 Token 也可以實現上面的需求,爲什麼要選擇這個框架?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前來說,筆者沒有十足的理由說服讀者必須使用哪種方案,此處也只是提供一種可行方案,至於實際應該選擇哪種方案,應該有讀者自己來考量,畢竟工具是否趁手還是需要試試才知道。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"如果是最多 100 個在線用戶,那怎麼裁剪系統?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"必要的組件只有 Orleans Dashboard 、 WebAPI 和 Claptrap Db。其他的組件全部都是非必要的。而且如果修改代碼, Orleans Dashboard 和 WebAPI 是可以合併的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以最小規模就是一個進程加一個數據庫。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Grafana 爲什麼沒有報表?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Grafana 首次啓動之後需要手動的創建 DataSource 和導入 Dashboard."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本實驗相關的參數如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"DataSource"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"URL: "},{"type":"link","attrs":{"href":"http://influxdb:8086/","title":null},"content":[{"type":"text","text":"http://influxdb:8086"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Database: metricsdatabase"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"User: claptrap"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Password: claptrap"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://github.com/newbe36524/Newbe.Claptrap/blob/develop/src/Docker/Monitor/grafana/claptrap.json","title":null},"content":[{"type":"text","text":"點擊此處獲取 Dashboard 定義文件"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"測試機的物理配置是什麼?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒有專門騰內存,未開始測試前已佔用 16GB 內存。以下是測試機的身材數據(洋垃圾,3500 元左右):"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"處理器 英特爾 Xeon (至強) E5-2678 v3 @ 2.50GHz 12 核 24 線程"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主板 HUANANZHI X99-AD3 GAMING (Wellsburg)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"顯卡 Nvidia GeForce GTX 750 Ti (2 GB / Nvidia)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"內存 32 GB (三星 DDR3L 1600MHz) 2013 年產 高齡內存"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主硬盤 金士頓 SA400S37240G (240 GB / 固態硬盤)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果您有更好的物理配置,相信可以得出更加優秀的數據。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"即使是 0.3 MB 平均每用戶的佔用的我也覺得太高了"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"框架還在優化。未來會更好。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"最後但是最重要!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最近作者正在構建以"},{"type":"codeinline","content":[{"type":"text","text":"反應式"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"Actor模式"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"事件溯源"}]},{"type":"text","text":"爲理論基礎的一套服務端開發框架。希望爲開發者提供能夠便於開發出 “分佈式”、“可水平擴展”、“可測試性高” 的應用系統 ——Newbe.Claptrap"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本篇文章是該框架的一篇技術選文,屬於技術構成的一部分。如果讀者對該內容感興趣,歡迎轉發、評論、收藏文章以及項目。您的支持是促進項目成功的關鍵。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"GitHub 項目地址:"},{"type":"link","attrs":{"href":"https://github.com/newbe36524/Newbe.Claptrap","title":null},"content":[{"type":"text","text":"https://github.com/newbe36524/Newbe.Claptrap"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Gitee 項目地址:"},{"type":"link","attrs":{"href":"https://gitee.com/yks/Newbe.Claptrap","title":null},"content":[{"type":"text","text":"https://gitee.com/yks/Newbe.Claptrap"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你對該項目感興趣,你可以通過 github issues 提交您的看法。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果您無法正常訪問 github issue,您也可以發送郵件到 "},{"type":"link","attrs":{"href":"mailto:[email protected]","title":null},"content":[{"type":"text","text":"[email protected]"}]},{"type":"text","text":" 來參與我們的討論。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"點擊鏈接 QQ 交流【Newbe.Claptrap】:"},{"type":"link","attrs":{"href":"https://jq.qq.com/?_wv=1027&k=5uJGXf5","title":null},"content":[{"type":"text","text":"https://jq.qq.com/?_wv=1027&k=5uJGXf5"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"​​​​​​​"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"本文作者: "},{"type":"text","text":"newbe36524"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"本文鏈接:"},{"type":"text","text":" "},{"type":"link","attrs":{"href":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/","title":null},"content":[{"type":"text","text":"https://www.newbe.pro/Newbe.Claptrap/How-Many-RAMs-In-Used-While-There-Are-One-Hundred-Thousand-Users-Online/"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"版權聲明: "},{"type":"text","text":"本博客所有文章除特別聲明外,均採用 "},{"type":"link","attrs":{"href":"https://creativecommons.org/licenses/by-nc-sa/4.0/","title":null},"content":[{"type":"text","text":"BY-NC-SA"}]},{"type":"text","text":" 許可協議。轉載請註明出處!"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章