最近做了一個搜尋介面的優化,反覆壓測了四次,終於達到要求了,記錄一下,晚上加個雞腿?
業務邏輯
從OpenSearch中檢索出資料,然後各種填充組裝資料,最後返回
邏輯看似很簡單,當初我也是這樣認為的,於是預估5天完成,最後前前後後開發、聯調、改bug直到上線差不多花了10天(當然這10天並不是只做這一件事情)
複雜在於影響返回結構的因素很多,排除問題需要檢查配置、檢查資料庫、檢查快取、檢查OpenSearch、檢查程式碼
言歸正傳,不管邏輯有多複雜,都不是你逃避問題的介面,更不是你不去優化的理由,這不是本文的重點,優化過程才是
要求,給APP提供的介面一般要求響應時間在100ms以內
第一次壓測
慘不忍睹,平均響應時間150ms,而且在這次壓測過程中還發現其它的問題,後臺報錯,經查是OpenSearch每秒查詢次數限制
優化程式碼與配置
1、修改OpenSearch配置,並且將壓測環境中的OpenSearch連線地址改為內網地址
2、將程式碼中迴圈查詢快取的地方改為一次性批量查詢返回
3、和相關同學確認後去掉專案中無用的程式碼
第二次壓測
雖然優化了程式碼,修改了配置,但是情況更糟糕了,而且還改出了新的問題
當時,反覆檢查了程式碼,確定查詢快取的次數已經是最少了,而且連線執行緒池相關引數也調到一個相對較大且合理的值了
如果,再壓測還是無法達到要求的話,只有出最後一招了:快取結果集
即,以使用者ID和使用者搜尋的關鍵詞為key,查詢的結果為value,快取5分鐘
第三次壓測
總算符合要求了,併發60的時候響應時間達到32ms,而我又發現了新的優化點
介面中居然還有查資料庫的操作,這可不能忍,排查之後去掉了一些不必要的依賴
成長
學會了使用RedisTemplate的executePipelined進行redis批量查詢
針對本次優化的總結
1、一定要絕對避免迴圈查資料庫和快取(PS:迴圈裡面就不能有查詢快取,更不能有查詢資料庫的操作,因為迴圈的次數沒法控制)
2、對於API介面的話,一般都是直接查快取的,沒有查資料庫的
3、多用批量查詢,少用單條查詢,儘量一次查出來
4、對於使用阿里雲,要留意一下相應產品的配置,該花的錢還是得花,同時,千萬要記得正式環境中使用相應產品的內網地址
5、注意連線池大小(包括資料庫連線池、Redis快取連線池、執行緒池)
6、壓測的機器上不要部署其它的服務,只跑待壓測的服務,避免受其它專案影響;對於線上環境,最好一臺機器上只部署一個重要的服務
7、沒有用的以及被註釋掉的程式碼,沒有用的依賴最好及時清理掉
8、叢集自不用說
9、一些監控類的工具工具可以幫助我們更好的定位問題,比如鏈路跟蹤,這次專案中使用了PinPoint
10、如果技術上優化的空間已經非常小了,可以試著從業務上著手,用實際的資料說話,可以從日常的訪問量,歷史訪問量資料來說服測試
11、每一次程式碼改動都有可能引入新的問題,因此,每次修改程式碼後都要回歸測試一下(PS:每次修改完以後,我都會用幾組不同的關鍵詞搜尋,然後比對修改前和修改後返回的資料是否一致,這個時候postman,以及Beyond compare就派上用場了)
12、關鍵的地方一定要多加點兒日誌,方便以後排除問題,因為排查線上問題最主要還是靠日誌
歡迎工作一到五年的Java工程師朋友們加入Java程式設計師開發: 721575865
群內提供免費的Java架構學習資料(裡面有高可用、高併發、高效能及分散式、Jvm效能調優、Spring原始碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!