1. 程式人生 > >48 張圖 | 手摸手教你微服務的效能監控、壓測和調優

48 張圖 | 手摸手教你微服務的效能監控、壓測和調優

![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210317102307754.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tzb24wNzE0,size_16,color_FFFFFF,t_70#pic_center) ![本文主要內容](https://img-blog.csdnimg.cn/img_convert/0ead02dc0f4529736802d962985ef0cd.png) > 開源專案 PassJava 地址:https://github.com/Jackson0714/PassJava-Platform > > 本文已收錄至:www.passjava.cn ## 一、何為壓力測試 ### 1.1、 大白話解釋 - 效能壓測是什麼:就是考察當前`軟體`和`硬體`環境下,系統所能承受的`最大負荷`,並幫助找出系統的`瓶頸`所在。 - 效能壓測的目的:為了系統在線上的`處理能力`和`穩定性`維持在一個`標準範圍`內,做到知己知彼,百戰不殆。還可以發現記憶體洩漏、併發與同步的問題。 ### 1.2、效能指標 - RepsonseTime - RT:響應時間,使用者從客戶端發起一個請求開始計算,到客戶端接收到服務端的響應結束,整個過程所耗費的時間。 - Hits Per Second - HPS:使用者每秒點選次數,也就是每秒向後臺傳送的請求次數。 - QPS:系統每秒內處理查詢的次數。 - MaxRT:最大響應時間,指使用者發出請求到服務端返回響應的最大時間。 - MiniRT:最少響應時間,指使用者發出請求到服務端返回響應的最少時間。 - 90%響應時間:將所有使用者的響應時間進行升序排序,取 90 % 的位置。 - 效能測試關注點: - 吞吐量:每秒鐘系統能處理的請求數、任務數。 - 響應時間:服務處理一個請求或一個任務的耗時。 - 錯誤率:一批請求中結果出過錯的請求所佔比例。 ## 二、Jmeter 壓測工具 ### 1、Jmeter 工具 - 下載和安裝 Jmeter 工具 ```bash 下載地址:https://jmeter.apache.org/download_jmeter.cgi 我下載的版本是 apache-jmeter-5.3 ``` ![](https://img-blog.csdnimg.cn/img_convert/8b33973211e6af588cea4d66427864ed.png) - 執行 JMeter 程式 開啟批處理檔案:\apache-jmeter-5.3\bin\jmeter.bat ![](https://img-blog.csdnimg.cn/img_convert/9394eb8e9e21b096dd718aece354d155.png) - 新增執行緒組 ![新增執行緒組](https://img-blog.csdnimg.cn/img_convert/fcb5e7b525cf592cbbe2b061cced6914.png) - 1s 內啟動 200 個執行緒,迴圈次數 100 次。2w 個請求。 ![](https://img-blog.csdnimg.cn/img_convert/343068fbe24af2f51949faa088efa800.png) - 測試 HTTP 請求 ![](https://img-blog.csdnimg.cn/img_convert/2fb320d0fefdfe8c72a9d629b69efc15.png) 配置要測試的協議、伺服器地址、埠號 協議:http 伺服器名稱或 IP: www.baidu.com (只是為了演示) 埠號:80 ![](https://img-blog.csdnimg.cn/img_convert/968761e1e6249c12cfca25af6f9e875f.png) - 新增察看結果樹、彙總報告和聚合報告 ![](https://img-blog.csdnimg.cn/img_convert/fa8614816e1e6e04df6730796917c895.png) - 開始壓力測試 點選播放按鈕就開始啟動了。注意啟動之前需要先設定執行緒組的引數配置和 HTTP 請求的配置。 ![](https://img-blog.csdnimg.cn/img_convert/244d6d62e872037e7ee3de8bb6d20c47.png) - 檢視每個請求結果 ![](https://img-blog.csdnimg.cn/img_convert/dad8b755fee01265db1ea22e57db3fa2.png) - 檢視彙總報告 主要關心平均值和吞吐量。 200 個執行緒,每個執行緒呼叫 100 次,總共 2 w 次,可以看到下圖中表格中的樣本列也是 2 w,請求所耗費的時間是 151 ms,吞吐量是 880 個請求每秒。 ![](https://img-blog.csdnimg.cn/img_convert/e630f82324d4be550eb4c4dc70b06f17.png) - 檢視聚合報告 主要看中位數和90%百分位,如下圖所示, **中位數**是 59 ms,說明大部分請求的響應時間是 59 ms。 **90 % 的請求** 都是在 271 ms 以內響應完成的。 **異常 0.41%** 說明 2 w 個請求中有 82 個請求異常(20000 * 0.0041 = 82 )。 **吞吐量 880.2/sec** 說明百度這個網站每秒能處理 880 個請求。效能還算可以。 ![](https://img-blog.csdnimg.cn/img_convert/5e5089d18ba60620c051fc945f01485c.png) - 檢視彙總圖 檢視彙總圖時,需要先勾選想要檢視的資訊 ![](https://img-blog.csdnimg.cn/img_convert/501784df9c1aba0599899c5a0535e3de.png) 然後檢視圖形彙總: ![](https://img-blog.csdnimg.cn/img_convert/cf6d85851b1984343598910d3e0a41c0.png) 可以看到勾選的幾列在圖表中是用不同顏色表示的,比如綠色的柱狀條就是 90 % 百分位。 我們來測試下 佳必過的管理後臺的效能,吞吐量接近 2000/s。 ![](https://img-blog.csdnimg.cn/img_convert/308de4ba0b94a7f9667780c2e7797e3e.png) ## 三、效能監控之 jconsole jconsole 和 jvisualvm 是 Java JDK 的兩個小工具,用來監控記憶體洩漏、跟蹤垃圾回收、執行時的記憶體情況、對 CPU 進行分析、執行緒的分析。都可以通過命令列啟動,而且可以監控本地和遠端應用。而 jvisualvm 是升級版的 jconsole。我們先來看下 jconsole 的使用。 首先用 cmd 命令列的方式啟動 jconsole。 ### 啟動 jconsole ![命令列啟動 jconsole](https://img-blog.csdnimg.cn/img_convert/4d2f4df5b6fea0d0625bf65e86489817.png) ### 選擇監控哪個應用 然後選擇 passjava 專案的 question 服務。 ![選擇 passjava-question 微服務](https://img-blog.csdnimg.cn/img_convert/8475056b049e5d8a124472bd7255620b.png) 對應的就是下面這個微服務: passjava-question ![對應 passjava-question 微服務](https://img-blog.csdnimg.cn/img_convert/b6f719d9d74b2294bd2d36333a834f09.png) ### 概覽 從監控介面上有 6 個選單,首先看到的是概覽功能,上面有堆記憶體使用量、執行緒數、類的使用情況、CPU 佔用率,都是用趨勢圖來表示的,能很方便的看出當前效能的概覽。注意:這些監控都是實時的。 ![概覽](https://img-blog.csdnimg.cn/img_convert/d96c05f6fa49da0dcdf2e27ae9a929f8.png) ### 記憶體 下面是記憶體的使用情況,可以從下圖中看到有個下拉框,裡面可以選擇不同的記憶體維度,然後下面的圖示和柱狀圖也會跟著選擇的維度而展示不同。 ![](https://img-blog.csdnimg.cn/img_convert/3779a386c80c7ff619a7d36731e87a70.png) ### 記憶體 下面是執行緒的使用情況,可以看到執行緒峰值和活動執行緒的總數量,目前看到的峰值是59,活動執行緒數是 57。下半部分可以看到具體是哪些執行緒,以及執行緒的堆疊資訊,非常詳細。 ![執行緒使用情況](https://img-blog.csdnimg.cn/img_convert/41add8f3062004f5bbfa0a9f85740f32.png) ### 類 下面是類的載入和解除安裝情況,已載入類總數是 10679,而已解除安裝的類是 1 個,所以當前已加裝當前類的總數是 10679 - 1 = 10678 個。 ![類的載入和解除安裝情況](https://img-blog.csdnimg.cn/img_convert/f3a8d1b410a99abc32f473b41b7df05b.png) ### VM 概要 我們再來看下VM(虛擬機器)的情況。如下圖所示,可以看到虛擬機器情況,執行緒、類、堆的概要資訊,以及 VM 的引數,是不是很方便呀~ ![VM 概要](https://img-blog.csdnimg.cn/img_convert/f3ecca538e4d0d613c76d9770e820e25.png) ### MBean 資訊 接下來我們來看下 MBean 資訊。對於 MBean,可能很多同學不知道是啥,下面做個解釋: MBean就是一種規範的JavaBean,通過整合和實現一套標準的Bean介面,這種叫MBean。MBean可以用來幹嘛?就是可以有一套JDK級別的對外的服務介面。比如,你寫了一個JVM允許狀態輔助查詢的Bean,你希望別人下載一個Jconsole就可以看到你寫的傑作。那你就可以考慮用MBean規範來實現。很多垃圾收集器演算法Bean就這麼幹的(說的就是這個類sun.management.MemoryImpl)。 ![MBean 資訊](https://img-blog.csdnimg.cn/img_convert/ac523e4d74a703c41ffba7b2d2d57bee.png) ## 四、效能監控之 jvisualvm jvisualvm 比 jconsole 更強大,介面展示的資訊更豐富。 ### 啟動 jvisualvm 和概述 啟動方式和 jconsole 一樣,也是通過 cmd 命令列啟動。還是選擇 passjava-question 微服務,然後選擇第一個選單欄:概述。可以看到 JVM 的版本,啟動引數等資訊。 ![啟動jvisualvm](https://img-blog.csdnimg.cn/img_convert/a187ba33454ebfc8ea6985805ea578b1.png) ### 監視 監視 CPU、堆、類、執行緒的情況。整體顯示的效果比 jconsole 更美觀。 ![監視](https://img-blog.csdnimg.cn/img_convert/06dde70962d0b051d50d05e88ac03854.png) ### 執行緒 再來查下執行緒的情況。可以看到有 5 種狀態的執行緒: - 執行:正在執行的執行緒。 - 休眠:休眠狀態的執行緒。 - 等待:等待執行的執行緒。 - 駐留:執行緒裡面的空閒執行緒。 - 監視:阻塞的執行緒,正在等待鎖。 ![](https://img-blog.csdnimg.cn/img_convert/6c6041a687bfb735e305408bc0a8caaa.png) ### 抽樣器 另外我們也可以抽樣器對 CPU 或記憶體進行抽樣。如下圖所示,對記憶體進行抽樣。 ![抽樣](https://img-blog.csdnimg.cn/img_convert/5c793a79a47a6a0805a9f7127092ba88.png) ### 外掛的使用 #### 安裝Visual GC 外掛 安裝步驟:工具->外掛->可用外掛->Visual GC->安裝。安裝完成後,重啟就可以使用外掛功能了。 ![](https://img-blog.csdnimg.cn/img_convert/00f53ce5f4c81d28222c0fcf6c2c8a53.png) 安裝完成後,就可以看到 ![Visual GC 外掛](https://img-blog.csdnimg.cn/img_convert/f2ef239cd7fb7d75b82a77dfa9bc51fa.png) 下圖是實時監控垃圾回收的情況。 ![Visual GC](https://img-blog.csdnimg.cn/img_convert/0c5ad825560521e7abfcfc2a2bc0b2e0.png) ## 五、對閘道器的效能測試 現在我想對 Passjava 系統的 question 微服務的介面進行一個壓測,該如何進行呢? 首先我們來看下 passjava 的架構是怎麼樣的,如下圖所示: ![](https://img-blog.csdnimg.cn/img_convert/25b921d7571d1060d55eb429206f4056.png) 客戶端分為手機端和 PC 端,http 請求先經過 API Gateway,然後再轉發到 question 微服務。其中涉及到了中介軟體:Gateway 閘道器。 我們來對 Gateway 閘道器進行壓力測試。 閘道器的埠號是 8060,我們配置下 JMeter。如下圖所示: ![](https://img-blog.csdnimg.cn/img_convert/3fb46db6fbb595828cc130e65f4695be.png) 配置每秒傳送 200 個請求,一直迴圈執行,直到手動停止壓測。如下圖所示: ![](https://img-blog.csdnimg.cn/img_convert/a3ce15fcd12e71df4b4cb80ebc5b3a35.png) 可以看下執行結果,吞吐量在 2422 個每秒,還是比較高的。 吞吐量:2422/s 。 90% 響應時間:142 毫秒。 99% 響應時間:281 毫秒。 ![](https://img-blog.csdnimg.cn/img_convert/1c71eae0ac70ff4dd1e8e76807bd1a77.png) 我們再來看看垃圾回收的情況,Eden 區垃圾回收用時 2.7 s,用時太長了吧,看看這裡怎麼能優化下。 通常的優化方向是增大新生代堆記憶體配置。 ![](https://img-blog.csdnimg.cn/img_convert/6b5ff65b79ed67041846944e698deb3f.png) ## 六、對微服務的效能測試 根據上面的架構原理圖,我們知道客戶端請求都是經過 Gateway 轉發了一次的,如果我們想單獨看下微服務的效能該怎麼測試呢?下面我來演示下如何測試 passjava-question 微服務的效能。 首先需要在 passjava-question 微服務中新增一個測試方法: ![測試方法](https://img-blog.csdnimg.cn/img_convert/29cdc005a8e928b7c7ce7b7452568d9f.png) 有兩種方式測試這個 api 是否新增正確。 第一種用 postman 測試下這個請求是否能正確響應,返回 “test” 則表示響應正確。 ![test api 是否能正確響應](https://img-blog.csdnimg.cn/img_convert/fde60206467bfc8951ad6435e6b14a5c.png) 第二種通過瀏覽器進行測試。瀏覽器位址列輸入以下連結後,回車,看下瀏覽器視窗是否顯示 “test”,是則表示響應正確。 然後我們需要用 Jmeter 壓測工具來測試這個微服務下的 api 的效能究竟如何。 ![單獨壓測微服務的 api的結果](https://img-blog.csdnimg.cn/img_convert/16f5eae40b8988c2730ddf5c97e2dedf.png) 吞吐量:3542/s 。 90% 響應時間:100 毫秒。 99% 響應時間:152 毫秒。 ## 七、對閘道器+微服務的效能測試 如果我們想對這個整個請求鏈路進行效能測試該怎麼做? 首先請求需要先經過閘道器,然後由閘道器轉發到微服務。在之前的文章中,我已經將閘道器配置好了,所以要想通過閘道器轉發到 test 請求,只需要對請求路徑稍作修改即可,如下所示: ```HTML http://localhost:8060/api/question/v1/admin/question/test ``` 然後在瀏覽器輸入該網址,返回 “test” 即表示響應正確。 然後我們還是用 Jmeter 壓測工具測試下 test api 的效能。測試結果如下圖所示: ![閘道器+微服務的壓力測試結果](https://img-blog.csdnimg.cn/img_convert/792c42af8583125e1e5b84013ab14469.png) 從結果可以看到: 吞吐量:982/s 。 90% 響應時間:437 毫秒。 99% 響應時間:790毫秒。 這裡做個橫向對比: ![橫向對比](https://img-blog.csdnimg.cn/img_convert/43c2e652bee5ebd5ee5a509ec76a8644.png) 說明微服務 api 經過閘道器轉發一次後,效能至少下降了一半。可以得出結果:中介軟體越多,效能損失越大,大部分損失都是網路互動導致的。可以通過增強網路通訊質量來減少網路的延遲。 ## 八、對資料庫查詢進行優化 一般情況下,出現效能問題更多的是業務中查詢資料庫的耗時。接下來看下如何優化資料的查詢。 下面是一個查詢問題列表的 api:通過問題型別 type 欄位過濾問題列表。api 路徑如下: ```html http://localhost:11000/question/v1/admin/question/list?type=5 ``` 這個 api 的程式碼如下,很容易看懂。 ![查詢問題列表的 api](https://img-blog.csdnimg.cn/img_convert/899a7637f378aa37de27f72d50ebe45c.png) 我們加些測試程式碼:統計查詢資料庫的耗時。如下所示: ![耗時統計](https://img-blog.csdnimg.cn/img_convert/18e11d292f3589bc68f0923f64af96cc.png) 然後重啟 passjava-question 服務,再次測試這個 api,耗時 43 ms ![](https://img-blog.csdnimg.cn/img_convert/f4f49bbdbed6360495dbc33438cf6051.png) 怎麼對查詢進行優化呢?很容易想到加索引,我們來試下加在 question 表加索引後的效果。給 type 欄位加上普通索引,如下圖所示: ![新增索引](https://img-blog.csdnimg.cn/img_convert/9bc76b5870c0a3b8480f03ec61d72480.png) 我們再來看下加了索引後的耗時情況:耗時 18 ms,確實比之前的 43 ms 快了很多。 ![加了索引後的情況](https://img-blog.csdnimg.cn/img_convert/d9f8d38ae103359594134e47da6dd9cd.png) ## 九、優化垃圾回收 我們可以通過 jvisulavm工具檢視垃圾回收的情況,Eden 區頻繁發生 GC,短時間(1分鐘)內共造成了 480 次 stop the world。另外從壓測工具中也可以看到,吞吐量為 275/s。 原因是 Eden 區的記憶體分配得太小了,只有 32 M,我們來調大一點。 ![32M Eden 區頻繁進行垃圾回收](https://img-blog.csdnimg.cn/img_convert/7704b030fba57010fbeb91334621e14a.png) ### 增大 Eden 區大小 通過在 IDEA 工具中配置以下引數,調整堆記憶體最大為 1024 M,新生代記憶體為 512 M。 ``` -Xmx1024m -Xms1024m -Xmn512m ``` 然後可以觀察到在短時間(1分鐘)內只進行了 92 次垃圾回收,說明垃圾回收的頻率降低了。應用程式的效能也提升了。另外從壓測工具中也可以看到,吞吐量為 347/s,吞吐量也有較大提升。 ![](https://img-blog.csdnimg.cn/img_convert/86cbe05e08def8bbc92d30c9cf1c86e2.png) ## 十、總結 本文通過壓測工具 Jmeter 講解壓測如何實施,然後用效能監控工具 jconsole 和 jvisualvm 來監控 Java 應用程式的效能,以及如何用工具來優化開源專案 passjava 的效能,並且非常詳細地介紹了每一步以及執行結果,通過對比的方式,更加清晰地知道如何做效能優化。 下面是對系統性能的常規優化手段: - 中介軟體較多時,優化網路通訊質量。 - 資料庫查詢耗時時,需要對查詢進行優化,比如新增索引。 - 模板的渲染速度,可以通過設定模板快取。 - 靜態資源的獲取,可以通過 Nginx 動靜分離來解決。(下期再講) - 日誌太多,需要減少不必要的打 log 操作。 巨人的肩膀: https://blog.csdn.net/u010833547/article/details/92806510 https://www.bilibili.com/video/BV1np4y1C7Yf https://github.com/Jackson0714/PassJava-Platform 開源專案 http://www.passjava.cn 我的網站 > **作者簡介**:悟空,8年一線網際網路開發和架構經驗,公眾號:悟空聊架構,用故事講解分散式、架構設計、Java 核心技術。《JVM效能優化實戰》專欄作者,開源了《Spring Cloud 實戰 PassJava》專案,自主開發了一個 PMP 刷題小程式。