From 9db28c74a4e901a3be01116c23c169d06b1192a0 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Tue, 29 Jun 2021 17:34:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=86=E5=9B=BE=E7=BC=93=E5=AD=98=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=92=E6=96=A5=E9=94=81=20=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E5=87=BA=E7=8E=B0=20=E7=BC=93=E5=AD=98=E5=87=BB?= =?UTF-8?q?=E7=A9=BF=E7=8E=B0=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/chart/ChartViewService.java | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 256a96f3ec..7f233d6fa5 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -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) 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 cacheViewData(DatasourceProvider datasourceProvider, DatasourceRequest datasourceRequest, String viewId) throws Exception{ + List 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)cache; + } + return result; + } + private void checkName(ChartViewWithBLOBs chartView) { // if (StringUtils.isEmpty(chartView.getId())) { // return;