Commit d36e0479 authored by daniel's avatar daniel

fix(cache): 数据更新时同步清除缓存,缓存key统一使用常量定义

parent 1e18f002
......@@ -2,10 +2,12 @@ package com.dlbridge.jadp.common.cache;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
......@@ -39,13 +41,24 @@ public class CacheTemplate {
@Resource
private ValueOperations<String, Object> valueOperations;
@Resource
private RedisTemplate<String, Object> redisTemplate;
/** 各命名空间对应的本地 Guava 缓存,按需创建 */
private final ConcurrentHashMap<String, Cache<String, Object>> localCaches = new ConcurrentHashMap<>();
/** 默认本地缓存最大容量 */
private static final int DEFAULT_LOCAL_MAX_SIZE = 1000;
/** Redis key 统一前缀 */
private static final String REDIS_KEY_PREFIX = "gk:";
public static final String REDIS_KEY_PREFIX = "gk:";
// ===== 缓存命名空间常量 =====
public static final String NS_CMPT_INFO = "cmpt:info";
public static final String NS_CMPT_CUSTOMER = "cmpt:customer";
public static final String NS_CMPT_FUNC = "cmpt:func";
public static final String NS_CMPT_PARTNER = "cmpt:partner";
public static final String NS_CMPT_LIST_RESP = "cmpt:list:resp";
public static final String NS_CMPT_LIST_COUNT = "cmpt:list:count";
/**
* 两级缓存查询(自动降级:L1 → L2 → L3)
......@@ -115,6 +128,17 @@ public class CacheTemplate {
}
}
/**
* 按前缀批量清除 Redis 缓存 + 对应命名空间的本地缓存
*/
public void evictByPrefix(String namespace) {
evictLocal(namespace);
Set<String> keys = redisTemplate.keys(REDIS_KEY_PREFIX + namespace + ":*");
if (keys != null && !keys.isEmpty()) {
redisTemplate.delete(keys);
}
}
/**
* 按需创建本地缓存实例
*/
......
......@@ -191,7 +191,7 @@ public class CmptService {
public Page<List<Cmpt>> queryCmpt(Pageable page, Map<String, String> param) {
// 响应级缓存:同一筛选条件+分页 的所有用户看到相同结果,缓存1分钟
// 1000 req/s 下,60秒窗口内每个缓存key仅查DB一次,DB压力降至 < 0.02 req/s
String responseCacheKey = "cmpt:list:resp:" + param.get("userId") + ":" + param.get("type")
String responseCacheKey = CacheTemplate.REDIS_KEY_PREFIX + CacheTemplate.NS_CMPT_LIST_RESP + ":" + param.get("userId") + ":" + param.get("type")
+ ":" + param.get("keyword") + ":" + param.get("partnerId")
+ ":" + page.getPageNumber() + ":" + page.getPageSize();
Object cached = valueOperations.get(responseCacheKey);
......@@ -207,7 +207,7 @@ public class CmptService {
}
// count 短时缓存:同一筛选条件翻页时避免重复执行跨库COUNT查询
String countCacheKey = "cmpt:list:count:" + param.get("userId") + ":" + param.get("type") + ":" + param.get("keyword") + ":" + param.get("partnerId");
String countCacheKey = CacheTemplate.REDIS_KEY_PREFIX + CacheTemplate.NS_CMPT_LIST_COUNT + ":" + param.get("userId") + ":" + param.get("type") + ":" + param.get("keyword") + ":" + param.get("partnerId");
Long count = null;
Object cachedCount = valueOperations.get(countCacheKey);
if (cachedCount != null) {
......@@ -351,7 +351,7 @@ public class CmptService {
public Partner getPartnerById(String parnter) {
return cacheTemplate.get(
"cmpt:partner",
CacheTemplate.NS_CMPT_PARTNER,
parnter,
Partner.class,
5L, TimeUnit.MINUTES,
......
package com.dlbridge.jadp.plugins.cmpt.web;
import com.dlbridge.jadp.common.cache.CacheTemplate;
import com.dlbridge.jadp.common.interceptor.PageView;
import com.dlbridge.jadp.common.persistence.IStorageService;
import com.dlbridge.jadp.common.persistence.Result;
......@@ -50,6 +51,9 @@ public class CmptController {
@Resource
private CmptSettingService cmptSettingService;
@Resource
private CacheTemplate cacheTemplate;
@Value("${server.url}")
private String serverURL;
@Value("${timer.url}")
......@@ -239,6 +243,11 @@ public class CmptController {
cmptService.save(cmpt);
} else {
cmptService.update(cmpt);
cacheTemplate.evict(CacheTemplate.NS_CMPT_INFO, String.valueOf(cmpt.getCmptId()));
cacheTemplate.evict(CacheTemplate.NS_CMPT_CUSTOMER, String.valueOf(cmpt.getCmptId()));
cacheTemplate.evict(CacheTemplate.NS_CMPT_FUNC, String.valueOf(cmpt.getCmptId()));
cacheTemplate.evictByPrefix(CacheTemplate.NS_CMPT_LIST_RESP);
cacheTemplate.evictByPrefix(CacheTemplate.NS_CMPT_LIST_COUNT);
}
return com.neusoft.www.utils.web.Result.success().setContent(cmpt);
......
......@@ -2,6 +2,7 @@ package com.dlbridge.jadp.plugins.cmpt.web;
import com.dlbridge.feign.GeexekScoreService;
import com.dlbridge.feign.bean.News;
import com.dlbridge.jadp.common.cache.CacheTemplate;
import com.dlbridge.jadp.common.interceptor.PageView;
import com.dlbridge.jadp.plugins.cmpt.bean.CmptSettingTemplate;
import com.dlbridge.jadp.plugins.cmpt.bean.FuncSetting;
......@@ -61,6 +62,9 @@ public class CmptSettingController {
@Resource
private GeexekScoreService geexekScoreService;
@Resource
private CacheTemplate cacheTemplate;
/**
* 去功能管理页面
*
......@@ -155,6 +159,9 @@ public class CmptSettingController {
count = cmptSettingService.updateByType(cmptSetting);
}
if (count > 0) {
if (cmptSetting.getCmptId() != null) {
cacheTemplate.evict(CacheTemplate.NS_CMPT_FUNC, cmptSetting.getCmptId());
}
return new Result().setCode(200).setMsg("更新成功!");
}else{
return new Result().setCode(-1).setMsg("更新失败!");
......@@ -166,6 +173,7 @@ public class CmptSettingController {
@ResponseBody
public Result updateSettingOrder(String ids) {
cmptSettingService.updateSettingOrder(ids);
cacheTemplate.evictByPrefix(CacheTemplate.NS_CMPT_FUNC);
return Result.success();
}
......
package com.dlbridge.jadp.plugins.cmpt.web;
import com.dlbridge.jadp.common.cache.CacheTemplate;
import com.dlbridge.jadp.plugins.cmpt.bean.Customer;
import com.dlbridge.jadp.plugins.cmpt.dao.model.Cmpt;
import com.dlbridge.jadp.plugins.cmpt.service.CmptService;
......@@ -25,6 +26,9 @@ public class CustomerController {
@Resource
CustomerService customerService;
@Resource
private CacheTemplate cacheTemplate;
@RequestMapping("index/{cmptId}")
public ModelAndView saveOrUpdate(@PathVariable("cmptId") Integer cmptId, ModelAndView mv){
Cmpt cmpt = cmptService.queryCmptBycmptId(cmptId);
......@@ -44,6 +48,7 @@ public class CustomerController {
@ResponseBody
public Result saveOrUpdate(Customer customer){
customerService.saveOrUpdate(customer);
cacheTemplate.evict(CacheTemplate.NS_CMPT_CUSTOMER, String.valueOf(customer.getCmptId()));
log.info("变更客服电话:"+customer);
return Result.success().setContent(customer);
}
......
......@@ -418,12 +418,12 @@ public class MicroApiController {
@ApiOperation(value = "赛事", notes = "赛事", tags = {"首页接口"})
public Result getCmpt(@PathVariable("cmptId") Integer cmptId) {
Cmpt cmpt = cacheTemplate.get(
"cmpt:info", // 缓存命名空间
String.valueOf(cmptId), // 缓存键
Cmpt.class, // 返回值类型
2L, TimeUnit.MINUTES, // L1 本地缓存 TTL
5L, TimeUnit.MINUTES, // L2 Redis 缓存 TTL
() -> cmptService.queryCmptBycmptId(cmptId) // L3 数据库回调
CacheTemplate.NS_CMPT_INFO,
String.valueOf(cmptId),
Cmpt.class,
2L, TimeUnit.MINUTES,
5L, TimeUnit.MINUTES,
() -> cmptService.queryCmptBycmptId(cmptId)
);
return Result.success().setContent(cmpt);
}
......@@ -434,7 +434,7 @@ public class MicroApiController {
@SuppressWarnings("unchecked")
public Result getCustomer(@PathVariable("cmptId") Integer cmptId) {
Map<String, String> result = cacheTemplate.get(
"cmpt:customer",
CacheTemplate.NS_CMPT_CUSTOMER,
String.valueOf(cmptId),
Map.class,
2L, TimeUnit.MINUTES,
......@@ -513,7 +513,7 @@ public class MicroApiController {
@SuppressWarnings("unchecked")
public Result<List<Func>> func(@PathVariable("cmptId") int cmpId, HttpServletRequest request) {
List<Func> list = cacheTemplate.get(
"cmpt:func",
CacheTemplate.NS_CMPT_FUNC,
String.valueOf(cmpId),
List.class,
2L, TimeUnit.MINUTES,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment