From ead1d79cfe64da6a2d8966d105477b64d0851e9e Mon Sep 17 00:00:00 2001 From: lucas <xie.yan@ipsos.com> Date: Wed, 31 Mar 2021 14:23:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=88=97=E5=87=BA=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=BC=93=E5=AD=98=EF=BC=8C=E5=B9=B6=E4=B8=94=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E6=B8=85=E7=A9=BA=E7=BC=93=E5=AD=98=EF=BC=8C=E4=B9=9F?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E5=8D=95=E4=B8=AA=E5=88=A0=E9=99=A4=E7=BC=93?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/monitor/CacheController.java | 17 +- ruoyi-ui/src/api/monitor/cache.js | 34 +- ruoyi-ui/src/views/monitor/cache/index.vue | 356 ++++++++++-------- 3 files changed, 242 insertions(+), 165 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java index fa9c623f2..6e86877f2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java @@ -9,9 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.StringUtils; @@ -48,6 +46,19 @@ public class CacheController pieList.add(data); }); result.put("commandStats", pieList); + result.put("allKeys", redisTemplate.keys("*")); return AjaxResult.success(result); } + + @PreAuthorize("@ss.hasPermi('monitor:cache:remove')") + @DeleteMapping("/{key}") + public AjaxResult delRedisCache(@PathVariable("key") String key) + { + try { + redisTemplate.delete(key); + return AjaxResult.success(); + } catch (Exception exception) { + return AjaxResult.error("删除失败,请告知管理员,说明这个错误:" + exception.getMessage()); + } + } } diff --git a/ruoyi-ui/src/api/monitor/cache.js b/ruoyi-ui/src/api/monitor/cache.js index 2ffaf7a3f..7a8089117 100644 --- a/ruoyi-ui/src/api/monitor/cache.js +++ b/ruoyi-ui/src/api/monitor/cache.js @@ -1,9 +1,25 @@ -import request from '@/utils/request' - -// 查询缓存详细 -export function getCache() { - return request({ - url: '/monitor/cache', - method: 'get' - }) -} +import request from '@/utils/request' + +// 查询缓存详细 +export function getCache() { + return request({ + url: '/monitor/cache', + method: 'get' + }) +} + +// 删除缓存 +export function delRedisCache(key) { + return request({ + url: '/monitor/cache/'+key, + method: 'delete' + }) +} + +// 清空缓存 +export function clearRedisCache() { + return request({ + url: '/monitor/cache/clear', + method: 'delete' + }) +} diff --git a/ruoyi-ui/src/views/monitor/cache/index.vue b/ruoyi-ui/src/views/monitor/cache/index.vue index 98eed22ec..c656c6d51 100644 --- a/ruoyi-ui/src/views/monitor/cache/index.vue +++ b/ruoyi-ui/src/views/monitor/cache/index.vue @@ -1,153 +1,203 @@ -<template> - <div class="app-container"> - <el-row> - <el-col :span="24" class="card-box"> - <el-card> - <div slot="header"><span>基本信息</span></div> - <div class="el-table el-table--enable-row-hover el-table--medium"> - <table cellspacing="0" style="width: 100%"> - <tbody> - <tr> - <td><div class="cell">Redis版本</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div></td> - <td><div class="cell">运行模式</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}</div></td> - <td><div class="cell">端口</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div></td> - <td><div class="cell">客户端数</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div></td> - </tr> - <tr> - <td><div class="cell">运行时间(天)</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div></td> - <td><div class="cell">使用内存</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div></td> - <td><div class="cell">使用CPU</div></td> - <td><div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div></td> - <td><div class="cell">内存配置</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div></td> - </tr> - <tr> - <td><div class="cell">AOF是否开启</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.aof_enabled == "0" ? "否" : "是" }}</div></td> - <td><div class="cell">RDB是否成功</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div></td> - <td><div class="cell">Key数量</div></td> - <td><div class="cell" v-if="cache.dbSize">{{ cache.dbSize }} </div></td> - <td><div class="cell">网络入口/出口</div></td> - <td><div class="cell" v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</div></td> - </tr> - </tbody> - </table> - </div> - </el-card> - </el-col> - - <el-col :span="12" class="card-box"> - <el-card> - <div slot="header"><span>命令统计</span></div> - <div class="el-table el-table--enable-row-hover el-table--medium"> - <div ref="commandstats" style="height: 420px" /> - </div> - </el-card> - </el-col> - - <el-col :span="12" class="card-box"> - <el-card> - <div slot="header"> - <span>内存信息</span> - </div> - <div class="el-table el-table--enable-row-hover el-table--medium"> - <div ref="usedmemory" style="height: 420px" /> - </div> - </el-card> - </el-col> - </el-row> - </div> -</template> - -<script> -import { getCache } from "@/api/monitor/cache"; -import echarts from "echarts"; - -export default { - name: "Server", - data() { - return { - // 加载层信息 - loading: [], - // 统计命令信息 - commandstats: null, - // 使用内存 - usedmemory: null, - // cache信息 - cache: [], - }; - }, - created() { - this.getList(); - this.openLoading(); - }, - methods: { - /** 查缓存询信息 */ - getList() { - getCache().then((response) => { - this.cache = response.data; - this.loading.close(); - - this.commandstats = echarts.init(this.$refs.commandstats, "macarons"); - this.commandstats.setOption({ - tooltip: { - trigger: "item", - formatter: "{a} <br/>{b} : {c} ({d}%)", - }, - series: [ - { - name: "命令", - type: "pie", - roseType: "radius", - radius: [15, 95], - center: ["50%", "38%"], - data: response.data.commandStats, - animationEasing: "cubicInOut", - animationDuration: 1000, - }, - ], - }); - this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons"); - this.usedmemory.setOption({ - tooltip: { - formatter: "{b} <br/>{a} : " + this.cache.info.used_memory_human, - }, - series: [ - { - name: "峰值", - type: "gauge", - min: 0, - max: 1000, - detail: { - formatter: this.cache.info.used_memory_human, - }, - data: [ - { - value: parseFloat(this.cache.info.used_memory_human), - name: "内存消耗", - }, - ], - }, - ], - }); - }); - }, - // 打开加载层 - openLoading() { - this.loading = this.$loading({ - lock: true, - text: "拼命读取中", - spinner: "el-icon-loading", - background: "rgba(0, 0, 0, 0.7)", - }); - }, - }, -}; -</script> +<template> + <div class="app-container"> + <el-row> + <el-col :span="24" class="card-box"> + <el-card> + <div slot="header"><span>基本信息</span></div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <table cellspacing="0" style="width: 100%"> + <tbody> + <tr> + <td><div class="cell">Redis版本</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div></td> + <td><div class="cell">运行模式</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}</div></td> + <td><div class="cell">端口</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div></td> + <td><div class="cell">客户端数</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div></td> + </tr> + <tr> + <td><div class="cell">运行时间(天)</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div></td> + <td><div class="cell">使用内存</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div></td> + <td><div class="cell">使用CPU</div></td> + <td><div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div></td> + <td><div class="cell">内存配置</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div></td> + </tr> + <tr> + <td><div class="cell">AOF是否开启</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.aof_enabled == "0" ? "否" : "是" }}</div></td> + <td><div class="cell">RDB是否成功</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div></td> + <td><div class="cell">Key数量</div></td> + <td><div class="cell" v-if="cache.dbSize">{{ cache.dbSize }} </div></td> + <td><div class="cell">网络入口/出口</div></td> + <td><div class="cell" v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</div></td> + </tr> + </tbody> + </table> + </div> + </el-card> + </el-col> + + <el-col :span="12" class="card-box"> + <el-card> + <div slot="header"><span>命令统计</span></div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <div ref="commandstats" style="height: 420px" /> + </div> + </el-card> + </el-col> + + <el-col :span="12" class="card-box"> + <el-card> + <div slot="header"> + <span>内存信息</span> + </div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <div ref="usedmemory" style="height: 420px" /> + </div> + </el-card> + </el-col> + </el-row> + <el-row> + <el-col :xs="8" :sm="8" :md="8" :lg="6" :xl="3" v-for="key in cache.allKeys" :key="key" > + <div class="grid-content bg-purple" style="width: 95%; display: flex; justify-content: space-between; margin-bottom: 10px; font-size: 16px;"> + <div style="width: 10%; line-height: 36px; text-align: center;"> + <i class="el-icon-cpu" /> + </div> + <div :title="key" style="line-height: 36px; width: 80%; height: 36px; overflow: hidden; text-overflow:ellipsis; white-space:nowrap;"> + <label>{{ key }}</label> + </div> + <div style="width: 10%; line-height: 36px; cursor: pointer;" @click="delCache(key)"> + <i class="el-icon-delete-solid" /> + </div> + </div> + </el-col> + </el-row> + <el-row> + <el-alert + title="点击清空缓存,是把当前系统所用的整个index缓存库,直接清空,该操作不可逆,请慎重操作!" + type="error"> + </el-alert> + </el-row> + <el-row> + <el-button type="danger" icon="el-icon-delete" @click="clearCache" style="float: right" round>清空缓存</el-button> + </el-row> + </div> +</template> + +<script> +import { getCache } from "@/api/monitor/cache"; +import echarts from "echarts"; + +export default { + name: "Server", + data() { + return { + // 加载层信息 + loading: [], + // 统计命令信息 + commandstats: null, + // 使用内存 + usedmemory: null, + // cache信息 + cache: [], + }; + }, + created() { + this.getList(); + this.openLoading(); + }, + methods: { + /** 查缓存询信息 */ + getList() { + getCache().then((response) => { + this.cache = response.data; + this.loading.close(); + + this.commandstats = echarts.init(this.$refs.commandstats, "macarons"); + this.commandstats.setOption({ + tooltip: { + trigger: "item", + formatter: "{a} <br/>{b} : {c} ({d}%)", + }, + series: [ + { + name: "命令", + type: "pie", + roseType: "radius", + radius: [15, 95], + center: ["50%", "38%"], + data: response.data.commandStats, + animationEasing: "cubicInOut", + animationDuration: 1000, + }, + ], + }); + this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons"); + this.usedmemory.setOption({ + tooltip: { + formatter: "{b} <br/>{a} : " + this.cache.info.used_memory_human, + }, + series: [ + { + name: "峰值", + type: "gauge", + min: 0, + max: 1000, + detail: { + formatter: this.cache.info.used_memory_human, + }, + data: [ + { + value: parseFloat(this.cache.info.used_memory_human), + name: "内存消耗", + }, + ], + }, + ], + }); + }); + }, + // 打开加载层 + openLoading() { + this.loading = this.$loading({ + lock: true, + text: "拼命读取中", + spinner: "el-icon-loading", + background: "rgba(0, 0, 0, 0.7)", + }); + }, + // 删除缓存 + delCache(key) { + this.$confirm('是否确认删除缓存"' + key + '"的数据项?', "警告", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(function() { + return delRedisCache(key); + }).then(() => { + this.getList(); + this.msgSuccess("删除成功"); + }) + }, + // 删除缓存 + clearCache() { + this.$confirm('是否确认清空缓存? 该操作不可逆,请慎重操作!', "警告", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(function() { + return clearRedisCache(); + }).then(() => { + this.getList(); + this.msgSuccess("删除成功"); + }) + } + }, +}; +</script>