1. 程式人生 > >業務系統請求zabbix圖表效能調優

業務系統請求zabbix圖表效能調優

## 效能調優實踐 - [效能調優實踐](#%e6%80%a7%e8%83%bd%e8%b0%83%e4%bc%98%e5%ae%9e%e8%b7%b5) - [背景](#%e8%83%8c%e6%99%af) - [問題分析](#%e9%97%ae%e9%a2%98%e5%88%86%e6%9e%90) - [後端優化排查](#%e5%90%8e%e7%ab%af%e4%bc%98%e5%8c%96%e6%8e%92%e6%9f%a5) - [前端優化排查](#%e5%89%8d%e7%ab%af%e4%bc%98%e5%8c%96%e6%8e%92%e6%9f%a5) - [後端長響應排查](#%e5%90%8e%e7%ab%af%e9%95%bf%e5%93%8d%e5%ba%94%e6%8e%92%e6%9f%a5) - [zabbix server 優化](#zabbix-server-%e4%bc%98%e5%8c%96) - [總結](#%e6%80%bb%e7%bb%93) ### 背景 用 vue.js 的框架 ant-design vue pro 實現的一個監控系統,後端用第三方開源元件 zabbix 提供監控資料採集,前端的展示中一個頁面會同時請求 N 個圖表,頁面響應時間很慢,極端情況下甚至達到 10s , 使用者體驗很差,所以領導給了個小任務,優化整個頁面的請求響應。 領導發現頁面響應很慢,說了一句:“這些圖表顯示這麼慢,應該一開始就想著優化的”,這裡我覺得這個觀點有待商榷,最近在讀《重構》這本書,裡面的一個觀點我很認同:“做任何事情,先做出來,再優化”,這是一個應用面很廣的策略,跟 Linux 的哲學之一“單個程式負責一個小功能”的組織模式,都有廣泛用法;當工期有限的情況下,先把東西做出來(這裡不光指代程式,而是任何產品或者其他交付物),再考慮優化它,因為有了產出物才會有後續的東西,而且任何人不可能一開始就把所有的情況和變化的需求考慮得面面俱到。Linux 哲學裡的那句話同樣可以用於人員組織、社會分工合作方面,專人專事,讓專業人士來做(比如:黑人抬棺),效率不言而喻。 顯示很慢的圖如下: ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164527677-131338397.png) ### 問題分析 之前從來沒有做過效能優化和分析,這次從零開始優化,需要自己認真分析排查,這個頁面會請求同一個介面,不獲取不同監控指標的圖表資料,大概 10-20 個圖表渲染,在排查之前想到可能的效能瓶頸: - 前端頁面優化不好(前端用的 axios.all 來發送多個併發請求,頁面會在所有後端響應後才渲染,可能瓶頸在這裡) - 後端介面的併發沒有優化過,可能效能瓶頸在這裡 - zabbix 這個開源中介軟體的響應時間過慢,負載過高 - mysql 資料庫引擎沒有優化,造成效能過低 ### 後端優化排查 作為全棧開發者,首先想到的是從後端服務開始優化,而沒有優化經驗怎麼入手,當然是先找輪子了,Google 找了一下工具,有如下可用: - 阿里的 [Arthas java診斷工具](https://alibaba.github.io/arthas/) - [OneAPM](https://www.oneapm.com/ai/java/springboot.html)(鏈路追蹤,類似於 skywalking 之類的工具,甚至可以監測我的 springboot專案) - Oracle 的 Java Mission Control - 淘寶的Tprofiler、Jprofiler - [MyBatis-Plus 效能分析外掛](https://mp.baomidou.com/guide/performance-analysis-plugin.html)(這裡我的後端是 springboot + Mybatis-Plus , 這個外掛可以幫助我分析 SQL 慢查詢,打印出所有的查詢語句) 詢問了下同事,發現大家也沒什麼優化經驗,所以我選用了之前瞭解了一點的 Arthas 工具作為診斷。 進入 Arthas 的官網,可以用它的線上教程快速入門(它是一個沙盒的 linux 環境,能夠快速掌握 Arthas 的基礎使用和概念),然後,知道使用方法後,把 Arthas 的 jar 包放到我的 centos 線上測試環境中(Arthas 本身也支援 windows 的,可以本地除錯) ```bash java -jar arthas-boot.jar ``` ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164543416-1286098726.png) 然後用 trace 命令來追蹤某個方法呼叫鏈路上的耗時 ``` trace xxxx.xxx xxx ``` ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164556298-349484381.png) 此時,我們請求前端程式碼,就能在後臺看到對這個呼叫方法的每一步的耗時了 ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164610641-724093374.png) 此時,我們就可以去具體的程式碼分析耗時原因了,重複 trace 可以進一步精確定位哪個方法開銷最大。 Arthas 還有很多非常強大的功能,對於 java 程式設計師非常友好,建議自行探索: > [Arthas GitHub 地址](https://github.com/alibaba/arthas) > [Arthas 使用指南](https://www.jianshu.com/p/95449939cca3) 發現介面響應時間為 500 ms 後,感覺效能瓶頸可能不在後端(當然,這裡肯定還有一定的優化空間,但是不是主要矛盾) ### 前端優化排查 發現後端介面響應時長沒有那麼誇張之後,把目光放到了前端上來,F12 打開了 chrome 瀏覽器的開發者工具後,發現幾個問題: 1. 同一個介面併發了很多次 2. Stalled 和 Waiting(TTFB)很長 繼續 Google ,搜尋 同時傳送多個請求造成 chrome stalled 時長過大(當然用英文關鍵詞搜尋),果然在 stackoverflow 發現了這個問題的解答,[https://stackoverflow.com/questions/27513994/chrome-stalls-when-making-multiple-requests-to-same-resource],裡面提到了幾種解決方式: 1. 給 response header 增加 `Cache-Control: no-cache, no-store` ,這個我在後端增加後沒有效果,這裡別人討論的是瀏覽器的快取機制造成請求過慢 2. 給我們的請求 url 後面增加一個隨機數,比如 `?ran='+Math.random()` ,讓請求不一致,達到欺騙瀏覽器,讓它每次都發送一個**新**的請求,這個實驗後也不能讓響應時間變短 此時的我陷入了沉思,問題究竟處在哪裡?同事提醒我一個規律,超過 **6** 個請求後,後面的都會開始有一串灰色的長耗時(就是我們看到的 stalled),另外一個同事說好像是 jquery 的限制還是怎樣,繼續搜尋,發現這個是 瀏覽器對同一個域名的多併發請求個數的限制,參考博文: - [瀏覽器併發請求限制](https://blog.csdn.net/tianhouquan/article/details/78803601) - [百度同學的追查,未解決,但思路很好](http://fex.baidu.com/blog/2015/01/chrome-stalled-problem-resolving-process/) - [v2ex的方案討論](https://www.v2ex.com/t/580906) 發現了這個限制之後,我們把圖表的請求個數限制在6個以內,跟之前相比頁面渲染速度確實有明顯提升,規避了請求數量過多造成 stalled 的問題,當然,這個只是一種解決方案,v2ex 上的同學有很多其他可參考的解決方式。 參考騰訊的藍鯨監控裡的圖表繪製,它們採取了分頁請求控制數量,儘量給客戶展示少的圖表,同時提供每頁顯示更多的選擇(每頁 4 個圖表秒開,8個的時候就開始有 loading 的效果了) ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164630500-1375270249.png) ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164639356-571746336.png) 解決了前端超過 6 個請求的阻塞問題,問題到了有的請求 Waiting(TTFB)很長上來了,這又是個什麼呢?搜尋一番發現,這個是服務端的響應(看來後端還是很有優化空間的,參考博文:[ttfb是什麼](https://www.wpzhiku.com/wating-ttfb-too-long/)) ### 後端長響應排查 這個圖表請求介面有的會特別慢,甚至有的會 2-3 秒,定位到問題出在跟三方元件 zabbix-server 的請求互動上,這是非常需要優化的,開啟我們的 fiddle 抓包工具看請求: fiddle 使用小技巧 控制面板-Internet 選項-連線-區域網設定-代理伺服器(不勾選為 LAN 使用代理伺服器) ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164656776-376547601.png) 設定地程式碼的代理埠為 8888 (fiddle 預設使用的就是 8888) ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164712450-360665416.png) ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164722348-636644344.png) 這樣設定後,fiddle 就只會抓取我本地 idea 傳送的請求了,過濾掉了瀏覽器裡的干擾請求。 用 Fiddler 抓 Postman的模擬請求 ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164735163-1353204434.png) 每個圖表請求分三個: 1. 登入 zabbix 獲取 token 2. 請求監控項 3. 根據監控項獲取圖表 參考 zabbix 的官方文件,做了程式碼層面的優化: - 出於效能考慮,快取 token ,避免每次都登入請求一個新 token - 檢索監控項只檢索你需要的屬性(這一點比較好理解,zabbix 服務端我們用的 mysql 引擎,相當於只查詢特定的欄位,跟全表查效能肯定不一樣) ![](https://img2020.cnblogs.com/blog/1713736/202005/1713736-20200514164746141-1907754732.png) 後端優化還包括:用特定的監控項取代發現型別監控項(這個是發現磁碟介面過慢的原因,會發現 70 多個檔案目錄),請求某個主機的所有發現型別監控項寫到我們的業務庫(只請求一次)等; ### zabbix server 優化 單個後端請求的瓶頸在於我們用 zabbix api 去請求 zabbix server 所返回的過程,所以,對zabbix server 本身的優化也是整個鏈路的重要方面。參考 zabbix 的官方文件後,有這樣一些方面: - 歷史資料儲存時間儘可能的小,這樣資料庫不會超負荷執行,查詢的效率也更高 [https://www.zabbix.com/documentation/4.0/zh/manual/config/items/history_and_trends] - 調優zabbix的資料庫引擎,這個是調優最重要的部分(由於沒有 dba ,本人對資料庫調優也不懂,這個暫時無法做到,搜尋了下我們使用的 mysql 5.6 使用的是 InnoDB 引擎) [https://www.zabbix.com/documentation/4.0/zh/manual/appendix/performance_tuning] 對於 zabbix 本身優化官方文件還沒整個看一遍,等全部找一遍說不定能找到進一步壓榨效能的方法~ ### 總結 此次優化涉及了很多方面,前端、後端、伺服器等,優化後的使用者體驗得到了提升,也遇到了一些坑,不斷提高自己解決問題的能力,才是程式設計師的價值,