性能壓測總結

        最近公司上了一個大項目,在上線前進行了3周的全鏈路壓測,總結了不少優化點,這裏列舉一些,以供大家參考

        1、統一日誌處理的aop攔截冗餘

                在攔截aop時pointCut配置,將controller和service層都做了切入,導致很多地方的日誌造成了冗餘打印,再加上重複的aop攔截也很耗時,最終移除所有的主動攔截,pointCut只配置了一個註解,在需要日誌的地方,主動添加註解@AroundLog。

        2、log.info耗時比較嚴重

                我們已經配置了異步發送log,但是還是由於打的日誌過多,導致了寫磁盤加鎖嚴重,但是又不能一行日誌都不加,無法定位生產問題的,而且日誌的打印都採用了json化。最終的改動方案就是移除json化,只打印對象,對於出參較多的接口,只打印核心的幾個出參

        3、數據庫寫操作過慢

                這個問題是由於mybatis的generator配置不對,導致自動生成的insert語句爲了返回自增id,在sql前面先進行了一次查詢操作,最終改爲了配置useGeneratedKeys="true" keyProperty="id" keyColumn="id"這三個參數來返回。

        4、代碼調用冗餘

                這個是微服務的一個弊端,比如一個最基礎的服務,查詢商品信息,基本上其他所有的服務都會調用,如果商品服務本身有一些慢的話,每一個服務調一遍,鏈路稍微長一些的服務可能就會被拖垮,再加上相同數據重複查詢,造成了商品服務壓力過大

                但這個又好似誤解,微服務本來就是各自處理各自的業務,儘量避免了參數間相互依賴,所以針對該問題,我們也只是儘量做到了某些參數透傳,來解決該問題

        5、串行改爲並行/異步執行

                有些接口需要調用10+個外部服務,這些服務本身又不相互依賴,所以可以採用並行的方式,我們是採用了jdk自帶的CompletableFuture實現了並行調用

                另外也存在非主流程業務較慢,將其移入了異步方法調用中實現,比如發MQ,將同步發送改爲異步發送。

        6、並行/異步使用姿勢不正確

                這個接上條。在剛開始使用CompletableFuture時,由於對該工具的理解不夠,導致代碼是如下寫法:

CompletableFuture<Void> aFuture = CompletableFuture.supplyAsync(
  () -> queryFromA();,
  ExecutePool.getInstance().getExecutor()
);
// 獲取異步線程結果
ThreadsUtils.completableFutureGet(aFuture);
queryFromB();

                這裏的問題是,當使用get方法時,其實是阻斷了主線程,直到future裏的全部線程執行完成,才能拿到數據,然後再執行下面那個方法,造成了主線程的時間浪費。這裏是我的理解錯誤導致的,其實future在生成的時候,裏面的線程已經開始跑了,所以如果這個時候主線程還想幹點什麼事情,應該先去做,然後在調用get方法獲取future的值。所以這裏需要將queryFromB()方法移到get方法前面即可。

               在使用異步的時候,也踩了一個坑,使用spring的@Async註解實現異步時,其實效果和我們所瞭解的事務失效的概念一樣,這個異步不能放在主方法的同一個類中,需要另起一個類調用纔可以。這個是在查看日誌時發現異步的線程ThreadName竟然依然是主線程name,才發現使用姿勢不對的。

        7、禁用BeanUtils.copy()方法

               該方法耗時嚴重,具體原因就不列舉了。經過分析,最終採用了mapstruct工具實現了bean之間的複製工作

        8、線程池優化

               這個不光指的是異步線程池,也指tomcat線程池和數據庫線程池的優化,當然,我們爲了提升性能,採用了undertow做爲java容器,數據庫線程池採用了hikari。具體的優化參數就不列了,因爲畢竟不同的項目,環境不一樣。

        9、對下游接口的緩存

               這個需要針對實際情況做出判斷了,如果下游數據的短時間不一致對業務沒有影響或者影響不大,可以考慮採用緩存來提高RT

        10、對非核心業務進行降級

                這個被同事成爲壓測作弊^_^。因爲我們有一個服務調用了3個外部服務,都非常慢,但是這三個服務其實不調用也不影響使用,如優惠券服務,雙十一的時候如果屏蔽該接口,並不影響用戶購買商品,但是極大的提高了RT,所以我們對這些服務做了開關,在流量高的時候,屏蔽這些接口,保證接口的高響應

        11、本地壓測調試

                這個其實不叫性能優化,只是推薦個方法。剛開始的時候,是跟着團隊在壓測,只有輪到自己服務的時候纔可以壓,時間比較緊張,很多問題定位不到。我就自己在本地裝了jmeter和arthas,自己壓測自己分析,雖然時間上肯定會比服務器上慢,但是一些鏈路問題,高耗時接口還是可以定位到的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章