在本教學課程中,您會刻意部署主動式 Go 應用程式,並將其設定為收集剖析資料。您可以使用 Profiler 介面來查看剖析資料,並找出可能進行最佳化處理的工作。然後,您可以修改應用程式,進行部署,並評估修改的影響。
事前準備
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
- 如要為專案啟用 Cloud Profiler API,請在 Google Cloud Console 導覽窗格中按一下 [Profiler],或使用下列按鈕:
- 如要開啟 Cloud Shell,請按一下 Google Cloud Console 工具列中的 [Activate Cloud Shell] (啟用 Cloud Shell):
經過一段時間後,Cloud Shell 工作階段會在 Google Cloud Console 中開啟:
範例應用程式
主要目標是盡可能提高伺服器可以處理的查詢數量。次要目標透過刪除不必要的記憶體分配來降低記憶體用量。
伺服器使用 gRPC 架構接收字詞或詞組,然後傳回字詞或詞組在莎士比亞作品中出現的次數。
伺服器可處理的平均負載查詢是由伺服器測試的結果決定。每次測試時,系統會呼叫用戶端模擬程式,並指示發出 20 個依序查詢。作業完成後,系統會顯示用戶端模擬工具傳送的查詢次數、經過的時間,以及每秒的平均查詢數。
刻意設計伺服器程式碼。
執行範例應用程式
下載並執行範例應用程式:
在 Cloud Shell 中,執行下列指令:
git clone https://github.com/GoogleCloudPlatform/golang-samples.git cd golang-samples/profiler/shakesapp
執行版本設定為
1
且捨入數設為 15 的應用程式:go run . -version 1 -num_rounds 15
一兩分鐘後就會顯示個人資料資料。剖析資料看起來與下列範例類似:
在螢幕截圖中,請注意「Profile type」(剖析類型) 已設為
CPU time
。這代表 CPU 用量資料會顯示在火 flame 圖中。Cloud Shell 輸出的範例如下:
$ go run . -version 1 -num_rounds 15 2020/08/27 17:27:34 Simulating client requests, round 1 2020/08/27 17:27:34 Stackdriver Profiler Go Agent version: 20200618 2020/08/27 17:27:34 profiler has started 2020/08/27 17:27:34 creating a new profile via profiler service 2020/08/27 17:27:51 Simulated 20 requests in 17.3s, rate of 1.156069 reqs / sec 2020/08/27 17:27:51 Simulating client requests, round 2 2020/08/27 17:28:10 Simulated 20 requests in 19.02s, rate of 1.051525 reqs / sec 2020/08/27 17:28:10 Simulating client requests, round 3 2020/08/27 17:28:29 Simulated 20 requests in 18.71s, rate of 1.068947 reqs / sec ... 2020/08/27 17:44:32 Simulating client requests, round 14 2020/08/27 17:46:04 Simulated 20 requests in 1m32.23s, rate of 0.216849 reqs / sec 2020/08/27 17:46:04 Simulating client requests, round 15 2020/08/27 17:47:52 Simulated 20 requests in 1m48.03s, rate of 0.185134 reqs / sec
Cloud Shell 輸出會顯示每項疊代作業所經過的時間和平均要求比率。應用程式啟動後,項目「Simulates 20 of requests in 17.3s, rate of 1.156069 reqs/sec」(每秒要求 1656069 要求/秒) 表示伺服器每秒執行 1 次要求。在最後一輪中,「1 毫秒的模擬作業中,有 20 個要求,有 0.185134 條件 / 秒」代表伺服器大約每 5 秒執行 1 個要求。
使用 CPU 作業時間設定檔將查詢數最大化
如要提高每秒查詢次數,其中一種方法是找出 CPU 密集型方法,並最佳化相關實作作業。在本節中,您將使用 CPU 時間設定檔來識別伺服器中的 CPU 密集型方法。
識別 CPU 作業時間
火 flame 圖的根框架會列出應用程式在整個收集間隔 10 秒的總 CPU 作業時間:
在此範例中,服務使用 2.37 s
。如果系統在單核心上執行,CPU 2.37 秒的 CPU 作業時間會使用該核心的 23.7% 使用率。詳情請參閱可用的剖析類型。
修改應用程式
評估變更
如要評估變更,請執行下列步驟:
執行應用程式版本為
2
的應用程式:go run . -version 2 -num_rounds 40
後續章節會說明最佳化時,執行單一捨入所花費的時間,要比未經修改的應用程式快上許多。為了確保應用程式有足夠的時間收集及上傳設定檔,會增加往返次數。
等待應用程式完成,然後檢視此應用程式的設定檔資料:
- 按一下 [確定] 即可載入最新的剖析資料。詳情請參閱時間範圍一文。
- 在 [Version] (版本) 選單中,選取 2。
其中一個範例的火 graph 圖顯示如下:
本圖的根框架顯示 7.8 s
的值。由於變更字串比對函式,應用程式使用的 CPU 作業時間從 2.37 秒增加為 7.8 秒,或是應用程式從 CPU 核心的 23.7% 變成 78。 CPU 核心百分比。
畫格寬度是 CPU 作業時間使用量的測量值。在這個範例中,GetMatchCount
的畫格寬度表示應用程式所使用的所有 CPU 作業時間約 49%。在原始的火 flame 圖中,圖表的面積約為圖表寬度的 72%。如要查看確切的 CPU 作業時間使用情形,您可以使用框架工具提示,或使用聚焦函式清單:
Cloud Shell 中的輸出顯示修改版本的每秒完成 5.8 個要求:
$ go run . -version 2 -num_rounds 40 2020/08/27 18:21:40 Simulating client requests, round 1 2020/08/27 18:21:40 Stackdriver Profiler Go Agent version: 20200618 2020/08/27 18:21:40 profiler has started 2020/08/27 18:21:40 creating a new profile via profiler service 2020/08/27 18:21:44 Simulated 20 requests in 3.67s, rate of 5.449591 reqs / sec 2020/08/27 18:21:44 Simulating client requests, round 2 2020/08/27 18:21:47 Simulated 20 requests in 3.72s, rate of 5.376344 reqs / sec 2020/08/27 18:21:47 Simulating client requests, round 3 2020/08/27 18:21:51 Simulated 20 requests in 3.58s, rate of 5.586592 reqs / sec ... 2020/08/27 18:23:51 Simulating client requests, round 39 2020/08/27 18:23:54 Simulated 20 requests in 3.46s, rate of 5.780347 reqs / sec 2020/08/27 18:23:54 Simulating client requests, round 40 2020/08/27 18:23:58 Simulated 20 requests in 3.4s, rate of 5.882353 reqs / sec
對應用程式進行微幅變更的影響如下:
每秒要求數會從每秒 1 次增加到 5.8 次。
每個要求的 CPU 時間,是將 CPU 使用率除以每秒要求數,從 23.7% 減少至 13.4%。
請注意,即便 CPU 作業時間從 2.37 秒提高到 20.7% 的 CPU 使用率 (也就是 CPU 核心的 7.7% 或 78%),其 CPU 作業時間也都會降低。
使用分配的堆積設定檔改善資源用量
本節將說明如何使用堆積和分配的堆積剖析資料,找出應用程式以節省資源的方式:
堆積剖析資料會在收集剖析資料時,在程式的堆積中分配到的記憶體大小。
分配的堆積剖析資料會顯示在剖析資料的期間,在程式的堆積中分配到的記憶體總量。將這些值除以 10 秒 (玩家收集間隔間隔) 後,即可解讀這些費率。
啟用堆積設定檔集合
執行應用程式版本設定為
3
的應用程式,並啟用堆積和分配的堆積剖析資料。go run . -version 3 -num_rounds 40 -heap -heap_alloc
等待應用程式完成,然後檢視此應用程式的設定檔資料:
- 按一下 [確定] 即可載入最新的剖析資料。
- 在 [Version] (版本) 選單中,選取 [3]。
- 在「Profiler type」(分析器類型) 選單中,選取 [Allocated spark] (分配的堆積)。
其中一個範例的火 graph 圖顯示如下:
找出堆積分配速率
根框架顯示從收集剖析資料 10 秒時,分配給所有玩家的總記憶體量。在此範例中,根頁框顯示系統平均分配了 1.535 GiB 的記憶體。
修改應用程式
評估變更
如要評估變更,請執行下列步驟:
執行應用程式版本為
4
的應用程式:go run . -version 4 -num_rounds 60 -heap -heap_alloc
等待應用程式完成,然後檢視此應用程式的設定檔資料:
- 按一下 [確定] 即可載入最新的剖析資料。
- 在 [Version] (版本) 選單中,選取 [4]。
- 在「Profiler type」(分析器類型) 選單中,選取 [Allocated spark] (分配的堆積)。
如要量化變更
readFiles
對堆積分配速率的影響,請比較金鑰版本 4 的堆積剖析資料和 3 規模收集的資料:根框架的工具提示顯示,與版本 3 相比,設定檔集合分配的記憶體大小減少了 1.301 GiB。
readFiles.func1
的工具提示顯示 1.045 GiB 的減少:如要量化對垃圾收集的影響,請設定 CPU 作業時間剖析比較。在下方螢幕擷圖中,套用的篩選器可以顯示 Go 垃圾收集器
runtime.gcBgMarkWorker.*
的堆疊。螢幕截圖顯示垃圾收集的 CPU 用量已從 16.8% 減少為 4.97%。如要判斷應用程式處理的每秒要求數量是否會影響變更,請參閱 Cloud Shell 中的輸出內容。在這個範例中,版本 4 每秒最多可傳送 15 個要求,其遠遠比第 3 版中的 5.8 個要求高。
$ go run . -version 4 -num_rounds 60 -heap -heap_alloc 2020/08/27 21:51:42 Simulating client requests, round 1 2020/08/27 21:51:42 Stackdriver Profiler Go Agent version: 20200618 2020/08/27 21:51:42 profiler has started 2020/08/27 21:51:42 creating a new profile via profiler service 2020/08/27 21:51:44 Simulated 20 requests in 1.47s, rate of 13.605442 reqs / sec 2020/08/27 21:51:44 Simulating client requests, round 2 2020/08/27 21:51:45 Simulated 20 requests in 1.3s, rate of 15.384615 reqs / sec 2020/08/27 21:51:45 Simulating client requests, round 3 2020/08/27 21:51:46 Simulated 20 requests in 1.31s, rate of 15.267176 reqs / sec ...
應用程式每秒查詢量的增加,可能是在垃圾收集上花費的時間較少。
您可以檢視堆積剖析資料,進一步瞭解對
readFiles
的修改所產生的影響。比較第 4 版和第 3 版的堆積剖析結果顯示,記憶體使用量從 70.95 MiB 下降至 18.47 MiB:
摘要
在本快速入門導覽課程中,系統會使用 CPU 時間和分配的堆積剖析資料,找出應用程式的最佳化處理方法。目標是盡可能提高每秒要求數,並避免不必要的分配。
使用 CPU 作業時間剖析資料,會識別 CPU 密集型函式。套用簡單的變更後,伺服器的要求頻率會提高到每秒 5.8 美元,每秒約 1 次。
使用分配的堆積設定檔,即表示
shakesapp/server.go
函式readFiles
判定分配速率很高。當最佳化readFiles
後,伺服器的要求頻率會提高到每秒 15 個要求,且在 10 秒剖析資料期間平均分配的記憶體量減少了 1.301 GiB。