You've already forked FrameTour-BE
feat(service): 使用带TTL的缓存Map替换静态Map
- 新增TtlCacheMap类,用于实现带生存时间的缓存 - 在ScenicServiceImpl中使用TtlCacheMap替换原有的ConcurrentHashMap - 为不同类型的适配器创建了对应的缓存Map - 优化了缓存获取逻辑,增加了TTL支持 - 添加了缓存清理和统计功能
This commit is contained in:
@@ -13,6 +13,7 @@ import com.ycwl.basic.storage.StorageFactory;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.storage.exceptions.StorageUnsupportedException;
|
||||
import com.ycwl.basic.util.ScenicConfigManager;
|
||||
import com.ycwl.basic.util.TtlCacheMap;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -21,7 +22,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author:longbinbin
|
||||
@@ -32,6 +33,21 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class ScenicServiceImpl implements ScenicService {
|
||||
@Autowired
|
||||
private ScenicRepository scenicRepository;
|
||||
|
||||
// TTL缓存配置,默认10分钟过期
|
||||
private static final long DEFAULT_CACHE_TTL_MINUTES = 10;
|
||||
|
||||
// 使用TTL缓存替代静态Map
|
||||
private static final TtlCacheMap<Long, IStorageAdapter> scenicStorageAdapterCache =
|
||||
new TtlCacheMap<>(TimeUnit.MINUTES.toMillis(DEFAULT_CACHE_TTL_MINUTES));
|
||||
private static final TtlCacheMap<Long, IStorageAdapter> scenicTmpStorageAdapterCache =
|
||||
new TtlCacheMap<>(TimeUnit.MINUTES.toMillis(DEFAULT_CACHE_TTL_MINUTES));
|
||||
private static final TtlCacheMap<Long, IStorageAdapter> scenicLocalStorageAdapterCache =
|
||||
new TtlCacheMap<>(TimeUnit.MINUTES.toMillis(DEFAULT_CACHE_TTL_MINUTES));
|
||||
private static final TtlCacheMap<Long, IFaceBodyAdapter> scenicFaceBodyAdapterCache =
|
||||
new TtlCacheMap<>(TimeUnit.MINUTES.toMillis(DEFAULT_CACHE_TTL_MINUTES));
|
||||
private static final TtlCacheMap<Long, IPayAdapter> scenicPayAdapterCache =
|
||||
new TtlCacheMap<>(TimeUnit.MINUTES.toMillis(DEFAULT_CACHE_TTL_MINUTES));
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
@@ -39,10 +55,9 @@ public class ScenicServiceImpl implements ScenicService {
|
||||
return ApiResponse.success(scenicRepository.list(scenicReqQuery));
|
||||
}
|
||||
|
||||
private static final Map<Long, IStorageAdapter> scenicStorageAdapterMap = new ConcurrentHashMap<>();
|
||||
@Override
|
||||
public IStorageAdapter getScenicStorageAdapter(Long scenicId) {
|
||||
return scenicStorageAdapterMap.computeIfAbsent(scenicId, (key) -> {
|
||||
return scenicStorageAdapterCache.computeIfAbsent(scenicId, (key) -> {
|
||||
IStorageAdapter adapter;
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
||||
if (scenicConfig.getString("store_type") != null) {
|
||||
@@ -58,10 +73,9 @@ public class ScenicServiceImpl implements ScenicService {
|
||||
return adapter;
|
||||
});
|
||||
}
|
||||
private static final Map<Long, IStorageAdapter> scenicTmpStorageAdapterMap = new ConcurrentHashMap<>();
|
||||
@Override
|
||||
public IStorageAdapter getScenicTmpStorageAdapter(Long scenicId) {
|
||||
return scenicTmpStorageAdapterMap.computeIfAbsent(scenicId, (key) -> {
|
||||
return scenicTmpStorageAdapterCache.computeIfAbsent(scenicId, (key) -> {
|
||||
IStorageAdapter adapter;
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
||||
if (scenicConfig.getString("tmp_store_type") != null) {
|
||||
@@ -77,10 +91,9 @@ public class ScenicServiceImpl implements ScenicService {
|
||||
return adapter;
|
||||
});
|
||||
}
|
||||
private static final Map<Long, IStorageAdapter> scenicLocalStorageAdapterMap = new ConcurrentHashMap<>();
|
||||
@Override
|
||||
public IStorageAdapter getScenicLocalStorageAdapter(Long scenicId) {
|
||||
return scenicLocalStorageAdapterMap.computeIfAbsent(scenicId, (key) -> {
|
||||
return scenicLocalStorageAdapterCache.computeIfAbsent(scenicId, (key) -> {
|
||||
IStorageAdapter adapter;
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
||||
if (scenicConfig.getString("local_store_type") != null) {
|
||||
@@ -97,10 +110,9 @@ public class ScenicServiceImpl implements ScenicService {
|
||||
});
|
||||
}
|
||||
|
||||
private static final Map<Long, IFaceBodyAdapter> scenicFaceBodyAdapterMap = new ConcurrentHashMap<>();
|
||||
@Override
|
||||
public IFaceBodyAdapter getScenicFaceBodyAdapter(Long scenicId) {
|
||||
return scenicFaceBodyAdapterMap.computeIfAbsent(scenicId, (key) -> {
|
||||
return scenicFaceBodyAdapterCache.computeIfAbsent(scenicId, (key) -> {
|
||||
IFaceBodyAdapter adapter;
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
||||
if (scenicConfig.getString("face_type") != null) {
|
||||
@@ -113,10 +125,9 @@ public class ScenicServiceImpl implements ScenicService {
|
||||
});
|
||||
}
|
||||
|
||||
private static final Map<Long, IPayAdapter> scenicPayAdapterMap = new ConcurrentHashMap<>();
|
||||
@Override
|
||||
public IPayAdapter getScenicPayAdapter(Long scenicId) {
|
||||
return scenicPayAdapterMap.computeIfAbsent(scenicId, (key) -> {
|
||||
return scenicPayAdapterCache.computeIfAbsent(scenicId, (key) -> {
|
||||
IPayAdapter adapter;
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
||||
if (scenicConfig.getString("pay_type") != null) {
|
||||
@@ -128,4 +139,94 @@ public class ScenicServiceImpl implements ScenicService {
|
||||
return adapter;
|
||||
});
|
||||
}
|
||||
|
||||
// ==================== 缓存管理方法 ====================
|
||||
|
||||
/**
|
||||
* 清除指定景区的所有适配器缓存
|
||||
*
|
||||
* @param scenicId 景区ID
|
||||
*/
|
||||
public void clearScenicAdapterCache(Long scenicId) {
|
||||
log.info("清除景区 {} 的所有适配器缓存", scenicId);
|
||||
scenicStorageAdapterCache.remove(scenicId);
|
||||
scenicTmpStorageAdapterCache.remove(scenicId);
|
||||
scenicLocalStorageAdapterCache.remove(scenicId);
|
||||
scenicFaceBodyAdapterCache.remove(scenicId);
|
||||
scenicPayAdapterCache.remove(scenicId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有适配器缓存
|
||||
*/
|
||||
public void clearAllAdapterCache() {
|
||||
log.info("清除所有适配器缓存");
|
||||
scenicStorageAdapterCache.clear();
|
||||
scenicTmpStorageAdapterCache.clear();
|
||||
scenicLocalStorageAdapterCache.clear();
|
||||
scenicFaceBodyAdapterCache.clear();
|
||||
scenicPayAdapterCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动触发过期缓存清理
|
||||
*
|
||||
* @return 清理的过期缓存项总数
|
||||
*/
|
||||
public int cleanupExpiredCache() {
|
||||
log.info("手动触发过期缓存清理");
|
||||
int totalCleaned = 0;
|
||||
totalCleaned += scenicStorageAdapterCache.cleanupExpired();
|
||||
totalCleaned += scenicTmpStorageAdapterCache.cleanupExpired();
|
||||
totalCleaned += scenicLocalStorageAdapterCache.cleanupExpired();
|
||||
totalCleaned += scenicFaceBodyAdapterCache.cleanupExpired();
|
||||
totalCleaned += scenicPayAdapterCache.cleanupExpired();
|
||||
log.info("清理了 {} 个过期缓存项", totalCleaned);
|
||||
return totalCleaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存统计信息
|
||||
*
|
||||
* @return 缓存统计信息
|
||||
*/
|
||||
public String getCacheStats() {
|
||||
StringBuilder stats = new StringBuilder();
|
||||
stats.append("=== ScenicServiceImpl 缓存统计信息 ===\n");
|
||||
stats.append("Storage Adapter Cache: ").append(scenicStorageAdapterCache.getStats()).append("\n");
|
||||
stats.append("Tmp Storage Adapter Cache: ").append(scenicTmpStorageAdapterCache.getStats()).append("\n");
|
||||
stats.append("Local Storage Adapter Cache: ").append(scenicLocalStorageAdapterCache.getStats()).append("\n");
|
||||
stats.append("FaceBody Adapter Cache: ").append(scenicFaceBodyAdapterCache.getStats()).append("\n");
|
||||
stats.append("Pay Adapter Cache: ").append(scenicPayAdapterCache.getStats()).append("\n");
|
||||
return stats.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置所有缓存统计信息
|
||||
*/
|
||||
public void resetCacheStats() {
|
||||
log.info("重置所有缓存统计信息");
|
||||
scenicStorageAdapterCache.resetStats();
|
||||
scenicTmpStorageAdapterCache.resetStats();
|
||||
scenicLocalStorageAdapterCache.resetStats();
|
||||
scenicFaceBodyAdapterCache.resetStats();
|
||||
scenicPayAdapterCache.resetStats();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定景区缓存的剩余TTL时间
|
||||
*
|
||||
* @param scenicId 景区ID
|
||||
* @return 各类型适配器缓存的剩余TTL时间(毫秒)
|
||||
*/
|
||||
public String getScenicCacheTtl(Long scenicId) {
|
||||
StringBuilder ttlInfo = new StringBuilder();
|
||||
ttlInfo.append("景区 ").append(scenicId).append(" 缓存TTL信息:\n");
|
||||
ttlInfo.append("Storage: ").append(scenicStorageAdapterCache.getRemainTtl(scenicId)).append("ms\n");
|
||||
ttlInfo.append("TmpStorage: ").append(scenicTmpStorageAdapterCache.getRemainTtl(scenicId)).append("ms\n");
|
||||
ttlInfo.append("LocalStorage: ").append(scenicLocalStorageAdapterCache.getRemainTtl(scenicId)).append("ms\n");
|
||||
ttlInfo.append("FaceBody: ").append(scenicFaceBodyAdapterCache.getRemainTtl(scenicId)).append("ms\n");
|
||||
ttlInfo.append("Pay: ").append(scenicPayAdapterCache.getRemainTtl(scenicId)).append("ms\n");
|
||||
return ttlInfo.toString();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user