|
@@ -1,5 +1,8 @@
|
|
|
package com.qizhen.healsphere.web;
|
|
|
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.github.benmanes.caffeine.cache.Cache;
|
|
|
+import com.github.benmanes.caffeine.cache.stats.CacheStats;
|
|
|
import com.qizhen.healsphere.web.dto.GraphLabelDTO;
|
|
|
import com.qizhen.healsphere.web.dto.NodeDTO;
|
|
|
import com.qizhen.healsphere.web.dto.RespDTO;
|
|
@@ -11,12 +14,17 @@ import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.cache.CacheManager;
|
|
|
+import org.springframework.cache.annotation.CacheEvict;
|
|
|
import org.springframework.cache.annotation.Cacheable;
|
|
|
+import org.springframework.cache.caffeine.CaffeineCache;
|
|
|
import org.springframework.stereotype.Controller;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
import javax.validation.Valid;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.HashMap;
|
|
|
|
|
|
/**
|
|
|
* @Description: 朗通知识图谱控制层
|
|
@@ -34,6 +42,9 @@ public class KgController {
|
|
|
@Autowired
|
|
|
private KgFacade kgFacade;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private CacheManager cacheManager;
|
|
|
+
|
|
|
@ApiOperation(value = "获取图谱", notes = "获取图谱")
|
|
|
@RequestMapping(value = "/getGraph", method = RequestMethod.POST)
|
|
|
@ResponseBody
|
|
@@ -53,8 +64,11 @@ public class KgController {
|
|
|
@ResponseBody
|
|
|
@Cacheable(value = KGTREECACHE, key = "'kgtree:t_' + #kgTree.type + '_st_' + #kgTree.subType")
|
|
|
public RespDTO<TreeDTO> getTree(@RequestBody @Valid KgTree kgTree) {
|
|
|
- log.info("获取树形分类缓存成功");
|
|
|
- return RespDTO.onSuc(kgFacade.getTreeFac(kgTree));
|
|
|
+ log.info("Cache miss for key: kgtree:t_{}_st_{}, executing method...",
|
|
|
+ kgTree.getType(), kgTree.getSubType());
|
|
|
+ TreeDTO result = kgFacade.getTreeFac(kgTree);
|
|
|
+ log.info("Method executed, result will be cached");
|
|
|
+ return RespDTO.onSuc(result);
|
|
|
}
|
|
|
|
|
|
@ApiOperation(value = "查询节点", notes = "查询节点")
|
|
@@ -63,5 +77,93 @@ public class KgController {
|
|
|
public RespDTO<List<NodeDTO>> getNode(@RequestBody @Valid KgQuery kgQuery) {
|
|
|
return RespDTO.onSuc(kgFacade.getNode(kgQuery));
|
|
|
}
|
|
|
+
|
|
|
+ @ApiOperation(value = "清理树形分类缓存", notes = "清理树形分类缓存")
|
|
|
+ @RequestMapping(value = "/delKgTreeCache",method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ @CacheEvict(cacheNames = KGTREECACHE, allEntries = true)
|
|
|
+ public RespDTO<Boolean> delKgTreeCache() {
|
|
|
+ log.info("清理树形分类缓存成功");
|
|
|
+ return RespDTO.onSuc(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "获取缓存数据", notes = "获取指定key的缓存数据")
|
|
|
+ @RequestMapping(value = "/cache-stats", method = RequestMethod.GET)
|
|
|
+ @ResponseBody
|
|
|
+ public RespDTO<Map<String, Object>> getCacheStats() {
|
|
|
+ Map<String, Object> stats = new HashMap<>();
|
|
|
+
|
|
|
+ CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache(KGTREECACHE);
|
|
|
+ if (caffeineCache != null) {
|
|
|
+ Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
|
|
|
+
|
|
|
+ // 获取缓存统计信息
|
|
|
+ CacheStats cacheStats = nativeCache.stats();
|
|
|
+ stats.put("hitCount", cacheStats.hitCount());
|
|
|
+ stats.put("missCount", cacheStats.missCount());
|
|
|
+ stats.put("hitRate", cacheStats.hitRate());
|
|
|
+
|
|
|
+ // 获取所有缓存的key
|
|
|
+ Map<Object, Object> cacheData = nativeCache.asMap();
|
|
|
+ stats.put("cacheSize", cacheData.size());
|
|
|
+ stats.put("cacheKeys", cacheData.keySet());
|
|
|
+
|
|
|
+ // 获取具体缓存内容
|
|
|
+ stats.put("cacheContent", cacheData);
|
|
|
+ }
|
|
|
+
|
|
|
+ return RespDTO.onSuc(stats);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "获取指定key的缓存数据", notes = "获取指定key的缓存数据")
|
|
|
+ @RequestMapping(value = "/cache-data/{type}/{subType}", method = RequestMethod.GET)
|
|
|
+ @ResponseBody
|
|
|
+ public RespDTO<TreeDTO> getCacheData(@PathVariable Integer type, @PathVariable Integer subType) {
|
|
|
+ String cacheKey = String.format("kgtree:t_%d_st_%d", type, subType);
|
|
|
+ log.info("尝试获取缓存key: {}", cacheKey);
|
|
|
+
|
|
|
+ try {
|
|
|
+ CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache(KGTREECACHE);
|
|
|
+ if (caffeineCache == null) {
|
|
|
+ log.warn("未找到名为 {} 的缓存", KGTREECACHE);
|
|
|
+ return RespDTO.onError("Cache manager not found");
|
|
|
+ }
|
|
|
+
|
|
|
+ Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
|
|
|
+ Object value = nativeCache.getIfPresent(cacheKey);
|
|
|
+
|
|
|
+ if (value == null) {
|
|
|
+ log.info("未找到key为 {} 的缓存数据", cacheKey);
|
|
|
+ return RespDTO.onError("Cache data not found");
|
|
|
+ }
|
|
|
+
|
|
|
+ log.debug("获取到的缓存数据类型: {}", value.getClass().getName());
|
|
|
+
|
|
|
+ // 如果是RespDTO类型
|
|
|
+ if (value instanceof RespDTO) {
|
|
|
+ log.info("缓存数据是RespDTO类型");
|
|
|
+ return (RespDTO<TreeDTO>) value;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果是JSON字符串
|
|
|
+ if (value instanceof String) {
|
|
|
+ log.info("缓存数据是String类型,尝试解析JSON");
|
|
|
+ String jsonStr = (String) value;
|
|
|
+ TreeDTO treeDTO = JSONUtil.toBean(
|
|
|
+ JSONUtil.parseObj(jsonStr).getObj("data").toString(),
|
|
|
+ TreeDTO.class
|
|
|
+ );
|
|
|
+ return RespDTO.onSuc(treeDTO);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其他类型的处理
|
|
|
+ log.warn("未知的缓存数据类型: {}", value.getClass().getName());
|
|
|
+ return RespDTO.onError("Unknown cache data type");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("获取缓存数据失败", e);
|
|
|
+ return RespDTO.onError("获取缓存数据失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|