提交 9db28c74 authored 作者: fit2cloud-chenyw's avatar fit2cloud-chenyw

feat: 视图缓存 增加互斥锁 避免出现 缓存击穿现象

上级 6afe2bdb
......@@ -34,6 +34,7 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
......@@ -55,6 +56,9 @@ public class ChartViewService {
@Resource
private ExtChartGroupMapper extChartGroupMapper;
//默认使用非公平
private ReentrantLock lock = new ReentrantLock();
public ChartViewWithBLOBs save(ChartViewWithBLOBs chartView) {
checkName(chartView);
long timestamp = System.currentTimeMillis();
......@@ -219,8 +223,7 @@ public class ChartViewService {
} else {
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList));
}
// String key = "provider_sql_"+datasourceRequest.getDatasource().getId() + "_" + datasourceRequest.getTable() + "_" +datasourceRequest.getQuery();
// 定时抽取使用缓存
/*// 定时抽取使用缓存
Object cache;
// 仪表板有参数不实用缓存
if (CollectionUtils.isNotEmpty(requestList.getFilter())) {
......@@ -228,13 +231,15 @@ public class ChartViewService {
}
// 仪表板无参数 且 未缓存过该视图 则查询后缓存
else if ((cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, id)) == null) {
lock.lock();
data = datasourceProvider.getData(datasourceRequest);
CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, id, data, null, null);
}
// 仪表板有缓存 使用缓存
else {
data = (List<String[]>) cache;
}
}*/
data = cacheViewData(datasourceProvider, datasourceRequest, id);
}
if (StringUtils.containsIgnoreCase(view.getType(), "pie") && data.size() > 1000) {
data = data.subList(0, 1000);
......@@ -301,6 +306,35 @@ public class ChartViewService {
return dto;
}
/**
* 避免缓存击穿
* 虽然流量不一定能够达到击穿的水平
* @param datasourceProvider
* @param datasourceRequest
* @param viewId
* @return
* @throws Exception
*/
public List<String[]> cacheViewData(DatasourceProvider datasourceProvider, DatasourceRequest datasourceRequest, String viewId) throws Exception{
List<String[]> result ;
Object cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, viewId);
if (cache == null) {
if (lock.tryLock()) {// 获取锁成功
result = datasourceProvider.getData(datasourceRequest);
if (result != null) {
CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, viewId, result, null, null);
}
lock.unlock();
}else {//获取锁失败
Thread.sleep(100);//避免CAS自旋频率过大 占用cpu资源过高
result = cacheViewData(datasourceProvider, datasourceRequest, viewId);
}
}else {
result = (List<String[]>)cache;
}
return result;
}
private void checkName(ChartViewWithBLOBs chartView) {
// if (StringUtils.isEmpty(chartView.getId())) {
// return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论