起因:
最近公司項目的公衆號有些接口返回數據的時間很久。
原因很簡單,因爲是Mysql數據庫而且數據量大概在500W條數據,接口響應時間在4S到5S.
體驗感太差勁了。so,我們來改造下。
改造思路:
1.SQL優化。
此接口的SQL關聯兩張表,主訂單,副產品,副貨道表
- a. 先把訂單表中多加入個貨道號的字段,減少一張表的關聯。
- b. 減少不需要的返回字段
這樣改造後,接口返回會快一丟丟。效果不明顯
2.我們直接把熱點數據加入緩存中。
我們常用的緩存是 redis, mongdb 等。
但是他們都有網絡開銷。
我決定用本地的cache來優化。
開始是準備用項目裏原來同事寫的一個全局變量類的,後來想起來在極客時間看的高併發編程40問裏面說的。
推薦使用google的 Google Guava 做本地緩存。
實現流程:
- 項目啓動後,定時任務把數據塞入到緩存
- 從緩存中把數據拿出來返回給前端
- 有定時任務按時刷新緩存中的數據
不多說上代碼:
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以內。
項目中還有挺多地方可以優化。
慢慢去修改吧、只要還給時間