【Google Guava 緩存】 上篇

在這裏插入圖片描述

起因:

最近公司項目的公衆號有些接口返回數據的時間很久。
原因很簡單,因爲是Mysql數據庫而且數據量大概在500W條數據,接口響應時間在4S到5S.
體驗感太差勁了。so,我們來改造下。

改造思路:

1.SQL優化。

此接口的SQL關聯兩張表,主訂單,副產品,副貨道表

  • a. 先把訂單表中多加入個貨道號的字段,減少一張表的關聯。
  • b. 減少不需要的返回字段

這樣改造後,接口返回會快一丟丟。效果不明顯

2.我們直接把熱點數據加入緩存中。

我們常用的緩存是 redis, mongdb 等。
但是他們都有網絡開銷。

我決定用本地的cache來優化。

開始是準備用項目裏原來同事寫的一個全局變量類的,後來想起來在極客時間看的高併發編程40問裏面說的。
推薦使用google的 Google Guava 做本地緩存。

實現流程:

  1. 項目啓動後,定時任務把數據塞入到緩存
  2. 從緩存中把數據拿出來返回給前端
  3. 有定時任務按時刷新緩存中的數據

不多說上代碼:


import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.math.BigDecimal;

/**
 * guava本地緩存工具類
 * @author bobo
 */
public final class GuavaCacheUtil {

    private static CacheBuilder<Object, Object> cacheBuilder
            = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .initialCapacity(10)
            .recordStats();

    private static Cache<String, Object> cache;
    static {
        cache = cacheBuilder.build();
    }

    private GuavaCacheUtil() {
    }

    /**
     * 添加緩存
     *
     * @param key
     * @param value
     */
    public static void set(String key, Object value) {
        cache.put(key, value);
    }

    /**
     * 刪除緩存
     *
     * @param key
     */
    public static void del(String key) {
        cache.invalidate(key);
    }

    /**
     * 根據key取得緩存對象
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        return cache.getIfPresent(key);
    }

    public static String getStr(String key) {
        return get(key).toString();
    }

    public static int getInt(String key) {
        Object value = get(key);
        if (value instanceof Integer) {
            return Integer.valueOf(value.toString());
        }
        return 0;
    }

    public static BigDecimal getBigDecimal(String key) {
        Object value = get(key);
        if (value instanceof BigDecimal) {
            return new BigDecimal(value.toString());
        }
        return BigDecimal.ZERO;
    }

    Cache<String, String> statsCache = CacheBuilder.newBuilder()
            .maximumSize(1000)
            .initialCapacity(1000)
            .recordStats() //開啓統計信息開關
            .build();
}


/** 業務中使用 **/
 @RequestMapping("getAll")
    public Object getAll(){
        List<BbaLog> bbaLogs = bbaLogMapper.findAny();
        if (bbaLogs.size()>0){
            GuavaCacheUtil.set("bba_log",bbaLogs);
            Object cacheLog = GuavaCacheUtil.get("bba_log");
            List<BbaLog> bbaLogList = (List<BbaLog>) cacheLog;
            for (BbaLog bbaLog : bbaLogList){
                System.err.println(bbaLog.getId());
            }
            return bbaLogList;
        }else {
            return "沒數據";
        }
    }

其實和別的Cache差不多。但是性能比他們高很多,我只是簡單的使用。
現在改造後,接口響應是1.99s,返回8000條數據。
但是實際接口數據的返回是87ms,但是8000數據Content Download的時間是1.90s.
優化下緩存中返回數據帶分頁效果,這樣速度肯定會更快。
暫時還沒優化完。
優化完後應該可以控制在100ms以內。


項目中還有挺多地方可以優化。
慢慢去修改吧、只要還給時間

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