From 897d400cbda233eb6878178a0f088a42da14fe60 Mon Sep 17 00:00:00 2001 From: "1437892690@qq.com" <1437892690@qq.com> Date: Fri, 16 May 2025 18:35:54 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[=E5=8A=9F=E8=83=BD]=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=8F=AF=E4=BB=A5=E5=9C=A8=E9=AB=98=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E5=9C=BA=E6=99=AF=E4=B8=8B=E9=98=B2=E6=AD=A2=E8=A2=AB?= =?UTF-8?q?=E5=87=BB=E7=A9=BF=E7=9A=84Mybaties=E4=BA=8C=E7=BA=A7=E7=BC=93?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 关联 #[1421727635046400]增加一个可以在高并发场景下防止被击穿的Mybaties二级缓存 http://192.168.0.96:8090/demo/rdm.html#/story-detail/939050947543040/939050947543042/1421727635046400 --- .../cache/NeatLogicConcurrentSafeCache.java | 22 ++++++++++------ .../framework/dao/mapper/LoginMapper.xml | 2 +- .../framework/dao/mapper/ModuleMapper.xml | 2 +- .../dao/plugin/SqlCostInterceptor.java | 25 +++++++++++++++++++ .../framework/dto/healthcheck/SqlAuditVo.java | 10 ++++++++ .../dao/mapper/FullTextIndexWordMapper.xml | 2 +- 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/main/java/neatlogic/framework/dao/cache/NeatLogicConcurrentSafeCache.java b/src/main/java/neatlogic/framework/dao/cache/NeatLogicConcurrentSafeCache.java index 60411433a..ba1a5226d 100644 --- a/src/main/java/neatlogic/framework/dao/cache/NeatLogicConcurrentSafeCache.java +++ b/src/main/java/neatlogic/framework/dao/cache/NeatLogicConcurrentSafeCache.java @@ -19,11 +19,10 @@ import neatlogic.framework.asynchronization.threadlocal.TenantContext; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; +import net.sf.ehcache.config.CacheConfiguration; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.cache.Cache; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -35,8 +34,6 @@ import java.util.concurrent.locks.ReentrantLock; * 高并发场景下,防止缓存击穿 */ public class NeatLogicConcurrentSafeCache implements Cache { - - private final static Logger logger = LoggerFactory.getLogger(NeatLogicConcurrentSafeCache.class); /** * The cache manager reference. */ @@ -76,12 +73,19 @@ public class NeatLogicConcurrentSafeCache implements Cache { } if (StringUtils.isNotBlank(tenant)) { if (!CACHE_MANAGER.cacheExists(tenant + ":" + id)) { - CACHE_MANAGER.addCache(tenant + ":" + id); + Ehcache ehcache = CACHE_MANAGER.addCacheIfAbsent(tenant + ":" + id); + CacheConfiguration cacheConfiguration = ehcache.getCacheConfiguration(); + // 缓存5分钟 + cacheConfiguration.setTimeToIdleSeconds(300); + cacheConfiguration.setTimeToLiveSeconds(300); } return CACHE_MANAGER.getEhcache(tenant + ":" + id); } else { if (!CACHE_MANAGER.cacheExists(id)) { - CACHE_MANAGER.addCache(id); + Ehcache ehcache = CACHE_MANAGER.addCacheIfAbsent(id); + CacheConfiguration cacheConfiguration = ehcache.getCacheConfiguration(); + cacheConfiguration.setTimeToIdleSeconds(600); + cacheConfiguration.setTimeToLiveSeconds(600); } return CACHE_MANAGER.getEhcache(id); } @@ -98,7 +102,7 @@ public class NeatLogicConcurrentSafeCache implements Cache { if (CollectionUtils.isNotEmpty(keys)) { for (Object key : keys) { ReentrantLock lock = LOCAL_LOCK_MAP.remove(generateLockKey(getId(), key)); - if (lock != null) { + if (lock != null && lock.isLocked()) { lock.unlock(); } } @@ -130,7 +134,9 @@ public class NeatLogicConcurrentSafeCache implements Cache { } cachedElement = getCache().get(key); if (cachedElement != null) { - lock.unlock(); + if (lock.isLocked()) { + lock.unlock(); + } return cachedElement.getObjectValue(); } return null; diff --git a/src/main/java/neatlogic/framework/dao/mapper/LoginMapper.xml b/src/main/java/neatlogic/framework/dao/mapper/LoginMapper.xml index 9bc2424f2..7cdd84155 100644 --- a/src/main/java/neatlogic/framework/dao/mapper/LoginMapper.xml +++ b/src/main/java/neatlogic/framework/dao/mapper/LoginMapper.xml @@ -16,7 +16,7 @@ along with this program. If not, see .--> - + SELECT diff --git a/src/main/java/neatlogic/framework/dao/plugin/SqlCostInterceptor.java b/src/main/java/neatlogic/framework/dao/plugin/SqlCostInterceptor.java index 73e6e3ac1..632f77c18 100644 --- a/src/main/java/neatlogic/framework/dao/plugin/SqlCostInterceptor.java +++ b/src/main/java/neatlogic/framework/dao/plugin/SqlCostInterceptor.java @@ -21,6 +21,8 @@ import neatlogic.framework.asynchronization.threadlocal.UserContext; import neatlogic.framework.dto.healthcheck.SqlAuditVo; import neatlogic.framework.healthcheck.SqlAuditManager; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.cache.Cache; import org.apache.ibatis.cache.CacheKey; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; @@ -120,6 +122,29 @@ public class SqlCostInterceptor implements Interceptor { //System.out.println(sql); sqlAuditVo.setSql(sql); sqlAuditVo.setId(sqlId); + if (Objects.equals(invocation.getMethod().getName(), "query")) { + CacheKey key = null; + Executor executor = (Executor) invocation.getTarget(); + Object[] args = invocation.getArgs(); + if (args.length > 4) { + key = (CacheKey) args[4]; + } else if (args.length == 4) { + Object parameterObject = args[1]; + RowBounds rowBounds = (RowBounds) args[2]; + key = executor.createCacheKey(mappedStatement, parameterObject, rowBounds, mappedStatement.getBoundSql(parameterObject)); + } + String useCacheLevel = StringUtils.EMPTY; + if (mappedStatement.getCache() != null) { + Cache cache = mappedStatement.getCache(); + if (cache.getObject(key) != null) { + useCacheLevel = "二级缓存"; + } + } + if (StringUtils.isBlank(useCacheLevel) && executor.isCached(mappedStatement, key)) { + useCacheLevel = "一级级缓存"; + } + sqlAuditVo.setUseCacheLevel(useCacheLevel); + } } } } catch (Exception e) { diff --git a/src/main/java/neatlogic/framework/dto/healthcheck/SqlAuditVo.java b/src/main/java/neatlogic/framework/dto/healthcheck/SqlAuditVo.java index 31a4b4ff4..950092e39 100644 --- a/src/main/java/neatlogic/framework/dto/healthcheck/SqlAuditVo.java +++ b/src/main/java/neatlogic/framework/dto/healthcheck/SqlAuditVo.java @@ -36,6 +36,8 @@ public class SqlAuditVo extends BasePageVo { private String tenant; @EntityField(name = "用户", type = ApiParamType.STRING) private String userId; + @EntityField(name = "使用到的缓存级别", type = ApiParamType.STRING) + private String useCacheLevel; public String getId() { return id; @@ -92,4 +94,12 @@ public class SqlAuditVo extends BasePageVo { public void setRecordCount(int recordCount) { this.recordCount = recordCount; } + + public String getUseCacheLevel() { + return useCacheLevel; + } + + public void setUseCacheLevel(String useCacheLevel) { + this.useCacheLevel = useCacheLevel; + } } diff --git a/src/main/java/neatlogic/framework/fulltextindex/dao/mapper/FullTextIndexWordMapper.xml b/src/main/java/neatlogic/framework/fulltextindex/dao/mapper/FullTextIndexWordMapper.xml index 93f0ffe8c..129752b3d 100755 --- a/src/main/java/neatlogic/framework/fulltextindex/dao/mapper/FullTextIndexWordMapper.xml +++ b/src/main/java/neatlogic/framework/fulltextindex/dao/mapper/FullTextIndexWordMapper.xml @@ -16,7 +16,7 @@ along with this program. If not, see .--> - +