性能比拼: .NET (C#) vs. Fiber (Go)

本內容是對知名性能評測博主 Anton Putra .NET (C#) vs. Fiber (Go): Performance (Latency - Throughput - Saturation - Availability) 內容的翻譯與整理, 有適當刪減, 相關指標和結論以原作為準


在本視頻中,我們將對比 C# 與 .NET 框架和 Golang 的表現。在第一個測試中,我們將專注于各自的最小框架實現。我們將測量 CPU 使用率、內存使用率、每秒可處理的請求數量,以及最重要的——最終用戶延遲。

我們會運行第一個測試直到其中一個應用程序失敗,然后再繼續運行一段時間,以找出另一個應用程序的崩潰臨界點。

在第二個測試中,我們將模擬一個常見的使用場景:從本地文件系統讀取一個文件(在本例中是圖片),然后將其上傳到 S3 存儲桶。同時,我們會將有關該圖片的一些元數據(比如使用時間戳、文件名等)保存到一個關系型數據庫中,例如 Postgres。此外,我們還會測量上傳圖片到 S3 的延遲以及將數據插入數據庫的查詢延遲。

基于之前的基準測試和反饋,我還會測量每個應用程序創建的數據庫連接數。

我們還將測量在云環境中啟動應用程序所需的時間。這不僅包括啟動時間,還包括拉取鏡像和通過健康檢查所需的時間。這將直接影響在云端的自動擴展能力。



對于 C# 我們將使用最新的 .NET 8 框架,這是由微軟構建并開源的跨平臺框架,它支持構建各種類型的應用程序,從簡單的 Web 應用與移動應用,到微服務和機器學習模型。

在本視頻中,我們將使用 .NET Core 框架搭配 Minimal API,以構建該語言與框架中最快的應用程序。

根據微軟的說法,這種設置在性能上應該優于 Golang。然而,他們的對比使用的是 Go 平臺上的 Gin 框架。


另一方面,對于Golang我們將使用 Fiber 框架,這是該語言中最快的 HTTP 框架之一。但有些人并不喜歡 Fiber,因為它并不完全兼容標準庫,因此并不是所有的中間件、可觀測性工具以及其他相關組件都能直接與 Fiber 一起使用。


現在,讓我們來看一下具體的測試。我有一個家用實驗室(Home Lab),使用 VMware Hypervisor 創建了一個多節點的 Kubernetes 集群。

我已經在 Kubernetes 中設置了一些監控組件:使用 Prometheus 服務器來抓取指標,Grafana 用于可視化這些指標并創建儀表盤,cAdvisor 用來抓取每個 Kubernetes 節點的指標,提供每個 Pod 的 CPU、內存與網絡使用情況。我還部署了 kube-state-metrics,我們將用它來測量啟動時間。

首先,我們將應用程序部署到 Kubernetes 集群。我有一個客戶端程序,可以配置來生成負載并測量每個請求的延遲。

測量延遲的最佳方式是使用外部客戶端,因為這能模擬任何最終用戶的真實體驗。當客戶端開始發送請求時,Prometheus 會抓取這些指標,并在儀表盤中展示。

在第二個測試中,我們將使用應用程序中的另一個端點 /api/images。每當客戶端發送請求時,應用程序會從本地文件系統讀取一個文件并上傳到 S3 存儲桶。我們不會使用 AWS S3,而是使用 MinIO,它是一個兼容 S3 的對象存儲,同樣部署在 Kubernetes 中。

在客戶端上傳圖片之后,我們會將一些圖片的元數據(比如創建時間戳、文件名等)寫入一個關系型數據庫——Postgres,這也部署在 Kubernetes 中。

你可以在我的 GitHub 公共倉庫中找到每個應用程序的源代碼,以及用于部署監控組件的 Terraform 腳本、Helm 圖表和 YAML 文件。

在這個測試中,我們還將使用 Prometheus 客戶端對每個應用程序進行指標注入,用來測量一些特定函數的調用時間。例如,我們將跟蹤上傳圖片所需的時間,以及將數據寫入數據庫所需的時間。

因此,在第二個測試中,我們將從外部客戶端和應用程序本身中收集指標。

接下來,我們來比較兩個應用程序的鏡像大小。對于 .NET 應用程序,我們將使用多階段 Docker 構建,并在最終階段使用 distroless 鏡像。這樣可以減少最終鏡像的體積。你也可以使用 Alpine 作為最終階段的基礎鏡像,但那樣會增加 1 到 2 兆字節的大小。

對于 Go 應用程序,我們也將使用多階段構建,并在最終階段使用 distroless 鏡像,這個鏡像由 Google 提供和構建。

現在,讓我們查看最終的鏡像大小。Go 的鏡像比 .NET 的小兩倍以上。實際上,你甚至可以將 Go 的鏡像壓縮到大約 39MB (使用go build -ldflags "-s -w")。更小的鏡像意味著 Kubernetes 在拉取鏡像和啟動應用程序時所需時間更短。


接下來,我們來測量啟動時間。這包括應用程序的啟動時間、Kubernetes 拉取鏡像的時間以及 Pod 通過健康檢查的時間。

這并不是一個非常科學的方法,因為網絡速度會極大地影響拉取鏡像的時間。但你仍然可以獲得一個大致的概念。我們可以使用 kube-state-metrics 來測量 Pod 就緒所需的時間。相關儀表盤也可以在我的代碼倉庫中找到。

好了,讓我們創建兩個 Pod,看看它們需要多長時間啟動。

由于鏡像更小,Golang 第一個啟動(耗時7s),而 C# 緊隨其后(耗時12s)。我多次運行了這個測試,并在每次之前都從 Kubernetes 節點中刪除了鏡像。如果你使用 Karpenter、自動擴縮容工具或云端的 Spot 節點,需要考慮 Kubernetes 每次都必須重新拉取鏡像。否則,兩者的啟動時間差異不大。

好了,我們開始第一次測試。首先,我會將這些應用程序部署到 Kubernetes,并在沒有任何負載的情況下運行大約 20 分鐘。

你可能會注意到 C# 的 CPU 使用率略高,但真正的區別在于內存使用。在空閑狀態下,C# 和 .NET 框架的內存消耗遠高于 Golang。

現在我們開始測試。首先,我們運行 10 個客戶端,持續約 5 分鐘,大約每個應用程序會接收到 20 個請求每秒。你會立即注意到 C# 的 CPU 使用率飆升,而且從客戶端側測量的整體延遲明顯更高。但內存使用幾乎沒有變化,因為我們只是返回了硬編碼的 JSON 數據。

接下來,我們增加到 50 個客戶端,大約是每秒 100 個請求。CPU 使用的差異變得更大,而延遲的差異保持一致。

現在,我們將客戶端數量增加到 200。整體延遲有所下降,但兩者之間的相對比例保持不變。此時,Golang 更高效,CPU 使用更少。

我們繼續,將客戶端數量增加到 400,測試 5 分鐘。

然后,我們將客戶端數量降到 5,觀察應用程序的適應能力。

接著,嘗試 10 個客戶端。

從現在開始,我們將從 550 個客戶端開始,每隔 5 分鐘持續增加,直到某個應用程序失敗。

當請求數達到每秒約 1200 時,.NET 應用程序開始丟棄部分請求。

請求達到每秒約 1300 時,.NET 應用程序開始出現故障,并伴隨延遲激增。我們會繼續運行幾分鐘。

最后,Golang 開始丟棄一些請求,但它的延遲仍保持在幾毫秒的范圍內。

整個測試持續了大約 2.5 小時。現在讓我打開各項圖表,查看整個測試期間的表現。

首先是 CPU 使用率圖表。

接著是內存使用圖表。

然后是每秒請求數圖表。

最后是整體延遲圖表。

這就是第一個測試的全部內容,我們對比了框架本身:.NET Minimal API 與 Golang Fiber 框架,兩者在 Kubernetes 中并行運行。



現在我們開始第二個測試,先從 10 個客戶端開始。你可以立刻看出 CPU 和內存使用顯著上升。同時我們還會測量延遲,看看讀取文件并上傳到 S3 所需的時間。目前來看,Golang 在低負載下表現更高效。我們還會測量保存文件元數據到關系型數據庫的延遲。

目前看起來,Golang 的性能更好,使用更少的 CPU 和內存完成任務。

接下來我們模擬一個突發流量,將客戶端數量暫時增加到 50,持續 5 分鐘。

S3 的延遲幾乎不變,但數據庫延遲的差異增大。

好了,我們將客戶端數量降回 10。

接下來的一個小時左右,我將逐步將客戶端數量從 100 增加到 200,以觀察哪一個應用程序表現更好。

你還可以看到 .NET 增加了連接池大小,而 Golang 保持相對穩定。我本可以手動設置連接池大小,但我的目標是測試這些框架和庫在默認設置下的表現,因為很多人就是這么使用的。

好了,我再運行幾分鐘的測試。到目前為止,這大概就是兩個應用程序所能處理的最大請求量了。你可以看到每秒請求數保持平穩。

現在讓我打開整個測試期間的 CPU 使用圖表。

接下來是內存使用圖表。

然后是數據庫延遲圖表。

這是每個應用程序的連接池大小圖。順便一提,Postgres 默認可以打開 100 個并發連接——至少這是我用 Helm 圖表部署數據庫時的默認設置。

現在是客戶端延遲圖表。

在每秒請求數指標中,你可以看到 Golang 實際上能處理更多請求。

最后是 S3 延遲圖表。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/94293.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/94293.shtml
英文地址,請注明出處:http://en.pswp.cn/web/94293.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

信譽代幣的發行和管理機制是怎樣的?

信譽代幣的發行與管理機制是區塊鏈技術與經濟模型深度融合的產物,其核心在于通過代碼和社區共識構建可量化、可驗證的信任體系。以下從技術架構、經濟模型、治理機制三個維度展開分析,并結合具體案例說明:一、發行機制:行為即價值…

神經網絡|(十二)概率論基礎知識-先驗/后驗/似然概率基本概念

【1】引言 前序學習進程中,對貝葉斯公式曾經有相當粗糙的回歸,實際上如果我們看教科書或者網頁,在講貝葉斯公式的時候,會有幾個名詞反復轟炸:先驗概率、后驗概率、似然概率。 今天就來把它們解讀一下,為以…

使用UE5開發《紅色警戒3》類戰略養成游戲的硬件配置指南

從零開始,學習 虛幻引擎5(UE5),開始游戲開發之旅!本文章僅提供學習,切勿將其用于不法手段!開發類似《紅色警戒3》級別的戰略養成游戲,其硬件需求遠超普通2D或小型3D項目——這類游戲…

Vue2+Vue3前端開發_Day12-Day14_大事件管理系統

參考課程: 【黑馬程序員 Vue2Vue3基礎入門到實戰項目】 [https://www.bilibili.com/video/BV1HV4y1a7n4] ZZHow(ZZHow1024) 項目收獲 Vue3 composition APIPinia / Pinia 持久化處理Element Plus(表單校驗,表格處理,組件封裝&#xff09…

[ACTF新生賽2020]明文攻擊

BUUCTF在線評測BUUCTF 是一個 CTF 競賽和訓練平臺,為各位 CTF 選手提供真實賽題在線復現等服務。https://buuoj.cn/challenges#[ACTF%E6%96%B0%E7%94%9F%E8%B5%9B2020]%E6%98%8E%E6%96%87%E6%94%BB%E5%87%BB下載查看,一個壓縮包和一張圖片。壓縮包需要密…

關于日本服務器的三種線路講解

租用日本服務器時,哪種線路選擇更適合?當初次接觸跨境業務的站長們著手租用日本服務器時,會發現不同服務商提供的網絡線路五花八門,從陌生的運營商名稱到復雜的技術參數,常常使其感到眼花繚亂。為了幫助大家理清思路,…

【大白話解析】 OpenZeppelin 的 MerkleProof 庫:Solidity 默克爾證明驗證工具全指南??(附源代碼)

?? 一、Merkle Tree 是什么?為什么要驗證它? 想象你有一個名單,比如: ["Alice", "Bob", "Charlie", "Dave"] 你想讓別人驗證:“我(比如 Alice)是不是在這個名單里?”,但不想把整個名單都放在區塊鏈上(太貴!)。 于是你…

機械學習綜合練習項目

數據集合完整項目文件已經上傳一、項目介紹案例介紹 案例是針對“紅酒.csv”數據集,在紅葡萄酒質量分析的場景 中,利用多元線性回歸來探索紅葡萄酒的不同化學成分如何共同 影響其質量評分。在建立線性回歸模型之后,當給出了紅葡萄酒 的新的一…

第3篇:配置管理的藝術 - 讓框架更靈活

前言 在前一章中,我們設計了強大的注解API。本章將深入探討配置管理系統的設計,學習如何將注解中的聲明式配置轉換為運行時可用的配置對象。 配置管理的核心挑戰 在我們的框架中,配置來源有三個層級:主要挑戰: &#x…

發版混亂怎么規范

你是否經歷過這種場景:臨到發版,一堆功能代碼擠在一起,測試分不清范圍,修復一個Bug可能引發三個新Bug?發布過程像一場豪賭?問題的核心往往在于分支策略和流程的混亂。今天,我們就來建立一套在絕…

【golang長途旅行第30站】channel管道------解決線程競爭的好手

channel 為什么需要channel 使用全局變量加鎖同步來解決goroutine的競爭,可以但不完美難以精確控制等待時間?(主線程無法準確知道所有 goroutine 何時完成)。全局變量容易引發競態條件?(即使加鎖,代碼復雜度也會增加…

蘋果XR芯片介紹

蘋果的 XR 芯片技術主要體現在 A 系列、M 系列處理器以及專為空間計算設計的 R1 協處理器中。以下從技術架構、產品迭代和綜合對比三個維度展開分析:一、技術架構解析1. A 系列芯片(以 A12 Bionic 為例)制程工藝:7nm(臺…

達夢數據庫巡檢常用SQL(三)

達夢數據庫巡檢常用SQL(三) 數據庫SQL運行檢查 數據庫SQL運行檢查 死鎖的事務情況: SELECT TO_CHAR(HAPPEN_TIME,YYYY-MM-DD HH24:MI:SS) HAPPEN_TIME,SQL_TEXT FROM V$DEADLOCK_HISTORY WHERE HAPPEN_TIME >DATEADD(DAY,-30,

基于SpringBoot的校園周邊美食探索及分享平臺

1. 項目簡介 項目名稱:校園周邊美食探索及分享平臺 項目背景:針對校園師生對周邊美食信息的需求,構建一個集美食推薦、鑒賞、評論互動及社交功能于一體的平臺,幫助用戶發現優質美食資源并進行分享交流。 主要目標: 提供…

Go數據結構與算法-常見的排序算法

雖然看過別人寫了很多遍,而且自己也寫過很多遍(指的是筆記),但是還是要寫的就是排序算法。畢竟是初學Go語言,雖然之前寫過,但是還是打算再寫一遍。主要包括插入排序、選擇排序、冒泡排序、快速排序、堆排序…

第 6 篇:目標規則與負載均衡 - `DestinationRule` 詳解

系列文章:《Istio 服務網格詳解》 第 6 篇:目標規則與負載均衡 - DestinationRule 詳解 本篇焦點: 深入理解 DestinationRule 的核心作用:定義流量在到達目的地之后的行為。 詳細剖析其三大核心功能:服務子集 (Subsets), 流量策略 (Traffic Policy), TLS 設置。 動手實戰…

一個簡潔的 C++ 日志模塊實現

一個簡潔的 C 日志模塊實現 1. 引言 日志功能在軟件開發中扮演著至關重要的角色,它幫助開發者追蹤程序執行過程、診斷問題以及監控系統運行狀態。本文介紹一個使用 C 實現的輕量級日志模塊,該模塊支持多日志級別、線程安全,并提供了簡潔易用…

C語言---數據類型

文章目錄數據類型分類1. 基本類型 (Basic Types)a. 整數類型 (Integer Types)char (字符型)int (整型)short (短整型)long (長整型)long long (C99標準引入)圖片匯總b. 浮點類型 (Floating-Point Types)float (單精度浮點型)double (雙精度浮點型)long double (長雙精度浮點型)…

本搭建烏云漏洞庫

1.下載鏡像站文件,并拖入虛擬機 2.將bugs.rar解壓至網站根目錄下 /var/www/html 3.配置bugs/conn.php 4.在bugs下創建upload目錄,將10-14、15-a、15-b、16壓縮包文件解壓到該upload目錄 5.把wooyun.rar解壓到 /mysql/data/wooyun目錄下 6.配置hosts文件后…

Vmware虛擬機 處理器配置選項配置介紹

1. 處理器配置選項好👌,我來幫你逐一解讀 VMware 里 虛擬機處理器 這些選項的含義。 你截的圖里,主要有三塊內容: 處理器數量 每個處理器的內核數量 ©虛擬化引擎1?? 處理器數量 這是分配給虛擬機的 邏輯 CPU 插槽數。一般…