目錄
- 一次接口優化記錄
- 首先考慮,添加緩存
- 緩存策略
- 方案一:本地緩存
- 方案二:Redis緩存
- 優化結果
- 原因分析:
- 原因驗證
- 接口數據分析
- 將響應數據返回大小減少
- compression壓縮配置
- 完美(代指這里的小系統)
一次接口優化記錄
背景:一個查詢文章的接口,有分頁,一臺二核四G的小服務器。redis也是這臺機子搭的單機Redis.
查詢速度:QPS在1-10之間。響應速度在一秒以上,可以說是極其的慢了。壓力測試直接壓到了100秒以上的響應速度。

首先考慮,添加緩存
緩存策略

步驟:
1、http請求過來
2、根據查詢條件,單表走索引查詢結果ID
3、根據結果ID去緩存中查詢數據,返回結果集
4、判斷是否都有緩存,沒有的單獨拎出來去查詢數據庫
5、將數據庫查詢結果添加到緩存中去。
6、將所有結果返回。
方案一:本地緩存
public static ConcurrentHashMap<Long, SysArticle> cache = new ConcurrentHashMap<>();private ArrayList<SysArticle> getSysArticlesByMapCache(List<Long> longs){List<Long> noHitIdList = new ArrayList<>();ArrayList<SysArticle> list = new ArrayList<>();// 根據Map從中查找IDfor (Long aLong : longs) {if(cache.containsKey(aLong)){list.add(cache.get(aLong));}else{noHitIdList.add(aLong);}}// 沒查詢到的從數據庫中查詢后放入Mapif (noHitIdList != null &&noHitIdList.size() > 0){List<SysArticle> articles = sysArticleService.selectSysArticleByArticleIds(noHitIdList.toArray(new Long[]{}), "");list.addAll(articles);for (SysArticle a : articles){cache.put(a.getArticleId(),a);}}return list;}}
方案二:Redis緩存
private ArrayList<SysArticle> getSysArticlesByRedisCache(List<Long> longs) {// 文章ID集Set idSet = new HashSet();for (Long aLong : longs) {idSet.add(String.valueOf(aLong));}// 根據ID集查詢redis緩存Map<String, Object> articleMap = RedisUtils.getMultiCacheMapValue(CACHE_KEY, idSet);// 查看是否有沒有緩存的文章,沒有則添加到待查詢列表List<Long> noHitIdList = new ArrayList<>(articleMap.size());for (Long id: longs){if (!articleMap.containsKey(String.valueOf(id))){noHitIdList.add(id);}}ArrayList<SysArticle> list = new ArrayList<>();for (Map.Entry<String, Object> longObjectEntry : articleMap.entrySet()) {list.add((SysArticle) longObjectEntry.getValue());}if(noHitIdList.size() > 0) { // 找出不存在的緩存,添加進去// 根據ID直接查詢文章List<SysArticle> articles = sysArticleService.selectSysArticleByArticleIds(noHitIdList.toArray(new Long[]{}), "");if (articles != null && articles.size() > 0) {// 添加到緩存,并且添加到返回列表中Map<String, SysArticle> collect = new HashMap<>();for (SysArticle a : articles) {collect.put(String.valueOf(a.getArticleId()), a);}RedisUtils.setCacheMap(CACHE_KEY, collect);list.addAll(articles);}}return list;}
優化結果
優化結果不明顯。可以說是一點都沒進步。甚至還退步。
主要還是第三個接口的響應時間過久。
原因分析:
1、線程池線程數量不足?
2、JVM空間不夠,頻繁回收?
3、Nginx有限制?
4、Redis性能過差?
5、網絡帶寬過低?
原因驗證
線程池線程數量不足?
擴大線程池數量,發現依舊不變。排除,況且業務并不繁忙,僅是簡單的查詢數據。
JVM空間不夠,頻繁回收?
使用率基本不超過20%,也排除。
Nginx有限制?
直接訪問ip請求,不走nginx,發現速度也沒變化
Redis性能過差?
直接在本機搭建Redis,減少網絡帶寬。況且redis可是能處理過萬的并發。我這才幾百。依舊沒有變化。
網絡帶寬過低?
可其他接口訪問也不低呀,為啥偏偏你就低。
接口數據分析

我:突然發現,一個接口返回50多KB。這接口返回的什么呀,這么大,
嗯: 返回了一大段的長文本文子。難怪那么大。
我: 看來也不是非必要數據,去除看看效果。

將響應數據返回大小減少

這就很舒服了。。。
等等,我覺得這個10kB還能優化。我記得SpringBoot有一個壓縮響應的配置的。再運用看看
compression壓縮配置
server:compression:#是否對響應數據開啟gzip壓縮,默認falseenabled: true#對指定的響應類型進行壓縮,值是數組,用逗號隔開mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml
開啟壓縮后

再來壓測一波
完美(代指這里的小系統)


