mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-18 04:55:06 +08:00
完成 Redis 监控的功能
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.dashboard.framework.redis.core;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
@ -14,15 +15,23 @@ import java.time.Duration;
|
||||
@Data
|
||||
public class RedisKeyDefine {
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum KeyTypeEnum {
|
||||
|
||||
STRING,
|
||||
LIST,
|
||||
HASH,
|
||||
SET,
|
||||
ZSET,
|
||||
STREAM,
|
||||
PUBSUB
|
||||
STRING("String"),
|
||||
LIST("List"),
|
||||
HASH("Hash"),
|
||||
SET("Set"),
|
||||
ZSET("Sorted Set"),
|
||||
STREAM("Stream"),
|
||||
PUBSUB("Pub/Sub");
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
@JsonValue
|
||||
private final String type;
|
||||
|
||||
}
|
||||
|
||||
@ -37,6 +46,7 @@ public class RedisKeyDefine {
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
@JsonValue
|
||||
private final Integer type;
|
||||
|
||||
}
|
||||
@ -63,25 +73,29 @@ public class RedisKeyDefine {
|
||||
* 过期时间
|
||||
*/
|
||||
private final Duration timeout;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private final String memo;
|
||||
|
||||
public RedisKeyDefine(String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) {
|
||||
private RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType,
|
||||
TimeoutTypeEnum timeoutType, Duration timeout) {
|
||||
this.memo = memo;
|
||||
this.keyTemplate = keyTemplate;
|
||||
this.keyType = keyType;
|
||||
this.valueType = valueType;
|
||||
this.timeoutType = TimeoutTypeEnum.FIXED;
|
||||
this.timeout = timeout;
|
||||
this.timeoutType = timeoutType;
|
||||
// 添加注册表
|
||||
RedisKeyRegistry.add(this);
|
||||
}
|
||||
|
||||
public RedisKeyDefine(String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) {
|
||||
this.keyTemplate = keyTemplate;
|
||||
this.keyType = keyType;
|
||||
this.valueType = valueType;
|
||||
this.timeoutType = timeoutType;
|
||||
this.timeout = Duration.ZERO;
|
||||
// 添加注册表
|
||||
RedisKeyRegistry.add(this);
|
||||
public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) {
|
||||
this(memo, keyTemplate, keyType, valueType, TimeoutTypeEnum.FIXED, timeout);
|
||||
}
|
||||
|
||||
public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) {
|
||||
this(memo, keyTemplate, keyType, valueType, timeoutType, Duration.ZERO);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ import java.util.List;
|
||||
*/
|
||||
public class RedisKeyRegistry {
|
||||
|
||||
/**
|
||||
* Redis RedisKeyDefine 数组
|
||||
*/
|
||||
private static final List<RedisKeyDefine> defines = new ArrayList<>();
|
||||
|
||||
public static void add(RedisKeyDefine define) {
|
||||
|
@ -1,25 +1,28 @@
|
||||
package cn.iocoder.dashboard.modules.infra.controller.redis;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.dashboard.common.pojo.CommonResult;
|
||||
import cn.iocoder.dashboard.framework.redis.core.RedisKeyDefine;
|
||||
import cn.iocoder.dashboard.framework.redis.core.RedisKeyRegistry;
|
||||
import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisKeyRespVO;
|
||||
import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisMonitorRespVO;
|
||||
import cn.iocoder.dashboard.modules.infra.convert.redis.RedisConvert;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.data.redis.connection.RedisServerCommands;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
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 javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
|
||||
|
||||
@Api("Redis 监控 API")
|
||||
@RestController
|
||||
@RequestMapping("/infra/redis")
|
||||
public class RedisController {
|
||||
@ -27,7 +30,8 @@ public class RedisController {
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
// @PreAuthorize("@ss.hasPermission('infra:redis:get-monitor-info')")
|
||||
@ApiOperation("获得 Redis 监控信息")
|
||||
@PreAuthorize("@ss.hasPermission('infra:redis:get-monitor-info')")
|
||||
@GetMapping("/get-monitor-info")
|
||||
public CommonResult<InfRedisMonitorRespVO> getRedisMonitorInfo() {
|
||||
// 获得 Redis 统计信息
|
||||
@ -36,33 +40,16 @@ public class RedisController {
|
||||
Properties commandStats = stringRedisTemplate.execute((
|
||||
RedisCallback<Properties>) connection -> connection.info("commandstats"));
|
||||
assert commandStats != null; // 断言,避免警告
|
||||
|
||||
// 拼接结果返回
|
||||
InfRedisMonitorRespVO respVO = InfRedisMonitorRespVO.builder().info(info).dbSize(dbSize)
|
||||
.commandStats(new ArrayList<>(commandStats.size())).build();
|
||||
commandStats.forEach((key, value) -> {
|
||||
respVO.getCommandStats().add(InfRedisMonitorRespVO.CommandStat.builder()
|
||||
.command(StrUtil.subAfter((String) key, "cmdstat_", false))
|
||||
.calls(Integer.valueOf(StrUtil.subBetween((String) value, "calls=", ",")))
|
||||
.usec(Integer.valueOf(StrUtil.subBetween((String) value, "usec=", ",")))
|
||||
.build());
|
||||
});
|
||||
return success(respVO);
|
||||
return success(RedisConvert.INSTANCE.build(info, dbSize, commandStats));
|
||||
}
|
||||
|
||||
// @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
|
||||
@ApiOperation("获得 Redis Key 列表")
|
||||
@PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')")
|
||||
@GetMapping("/get-key-list")
|
||||
public CommonResult<List<InfRedisKeyRespVO>> getKeyList() {
|
||||
List<InfRedisKeyRespVO> respVOList = RedisKeyRegistry.list().stream()
|
||||
.map(define -> InfRedisKeyRespVO.builder()
|
||||
.keyTemplate(define.getKeyTemplate())
|
||||
.keyType(define.getKeyType().name())
|
||||
.valueType(define.getValueType().getName())
|
||||
.timeoutType(define.getTimeoutType().getType())
|
||||
.timeout((int) define.getTimeout().getSeconds())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
return success(respVOList);
|
||||
List<RedisKeyDefine> keyDefines = RedisKeyRegistry.list();
|
||||
return success(RedisConvert.INSTANCE.convertList(keyDefines));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,33 +1,36 @@
|
||||
package cn.iocoder.dashboard.modules.infra.controller.redis.vo;
|
||||
|
||||
import cn.iocoder.dashboard.framework.redis.core.RedisKeyDefine;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@ApiModel("Redis Key 信息 Response VO")
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class InfRedisKeyRespVO {
|
||||
|
||||
/**
|
||||
* Key 模板
|
||||
*/
|
||||
private final String keyTemplate;
|
||||
/**
|
||||
* Key 类型的枚举
|
||||
*/
|
||||
private final String keyType;
|
||||
/**
|
||||
* Value 类型
|
||||
*/
|
||||
private final String valueType;
|
||||
/**
|
||||
* 超时类型
|
||||
*/
|
||||
private final Integer timeoutType;
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private final Integer timeout;
|
||||
@ApiModelProperty(value = "login_user:%s", required = true, example = "String")
|
||||
private String keyTemplate;
|
||||
|
||||
@ApiModelProperty(value = "Key 类型的枚举", required = true, example = "String")
|
||||
private RedisKeyDefine.KeyTypeEnum keyType;
|
||||
|
||||
@ApiModelProperty(value = "Value 类型", required = true, example = "java.lang.String")
|
||||
private Class valueType;
|
||||
|
||||
@ApiModelProperty(value = "超时类型", required = true, example = "1")
|
||||
private RedisKeyDefine.TimeoutTypeEnum timeoutType;
|
||||
|
||||
@ApiModelProperty(value = "过期时间,单位:毫秒", required = true, example = "1024")
|
||||
private Duration timeout;
|
||||
|
||||
@ApiModelProperty(value = "备注", required = true, example = "啦啦啦啦~")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.dashboard.modules.infra.controller.redis.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@ -7,26 +9,34 @@ import lombok.Data;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
@ApiModel("Redis 监控信息 Response VO")
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class InfRedisMonitorRespVO {
|
||||
|
||||
@ApiModelProperty(value = "Redis info 指令结果", required = true, notes = "具体字段,查看 Redis 文档")
|
||||
private Properties info;
|
||||
|
||||
@ApiModelProperty(value = "Redis key 数量", required = true, example = "1024")
|
||||
private Long dbSize;
|
||||
|
||||
private List<Object> commandStats;
|
||||
@ApiModelProperty(value = "CommandStat 数组", required = true)
|
||||
private List<CommandStat> commandStats;
|
||||
|
||||
@ApiModel("Redis 命令统计结果")
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public static class CommandStat {
|
||||
|
||||
@ApiModelProperty(value = "Redis 命令", required = true, example = "get")
|
||||
private String command;
|
||||
|
||||
@ApiModelProperty(value = "调用次数", required = true, example = "1024")
|
||||
private Integer calls;
|
||||
|
||||
@ApiModelProperty(value = "消耗 CPU 秒数", required = true, example = "666")
|
||||
private Integer usec;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.dashboard.modules.infra.convert.redis;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.dashboard.framework.redis.core.RedisKeyDefine;
|
||||
import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisKeyRespVO;
|
||||
import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisMonitorRespVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
@Mapper
|
||||
public interface RedisConvert {
|
||||
|
||||
RedisConvert INSTANCE = Mappers.getMapper(RedisConvert.class);
|
||||
|
||||
default InfRedisMonitorRespVO build(Properties info, Long dbSize, Properties commandStats) {
|
||||
InfRedisMonitorRespVO respVO = InfRedisMonitorRespVO.builder().info(info).dbSize(dbSize)
|
||||
.commandStats(new ArrayList<>(commandStats.size())).build();
|
||||
commandStats.forEach((key, value) -> {
|
||||
respVO.getCommandStats().add(InfRedisMonitorRespVO.CommandStat.builder()
|
||||
.command(StrUtil.subAfter((String) key, "cmdstat_", false))
|
||||
.calls(Integer.valueOf(StrUtil.subBetween((String) value, "calls=", ",")))
|
||||
.usec(Integer.valueOf(StrUtil.subBetween((String) value, "usec=", ",")))
|
||||
.build());
|
||||
});
|
||||
return respVO;
|
||||
}
|
||||
|
||||
List<InfRedisKeyRespVO> convertList(List<RedisKeyDefine> list);
|
||||
|
||||
}
|
@ -14,20 +14,12 @@ import static cn.iocoder.dashboard.framework.redis.core.RedisKeyDefine.KeyTypeEn
|
||||
*/
|
||||
public interface RedisKeyConstants {
|
||||
|
||||
/**
|
||||
* {@link LoginUser} 的缓存
|
||||
*
|
||||
* key 的 format 的参数是 sessionId
|
||||
*/
|
||||
RedisKeyDefine LOGIN_USER = new RedisKeyDefine("login_user:%s", STRING, LoginUser.class,
|
||||
Duration.ofMinutes(30));
|
||||
RedisKeyDefine LOGIN_USER = new RedisKeyDefine("登陆用户的缓存",
|
||||
"login_user:%s", // 参数为 sessionId
|
||||
STRING, LoginUser.class, Duration.ofMinutes(30));
|
||||
|
||||
/**
|
||||
* 验证码的缓存
|
||||
*
|
||||
* key 的 format 的参数是 uuid
|
||||
*/
|
||||
RedisKeyDefine CAPTCHA_CODE = new RedisKeyDefine("captcha_code:%s", STRING, String.class,
|
||||
RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
||||
RedisKeyDefine CAPTCHA_CODE = new RedisKeyDefine("验证码的缓存",
|
||||
"captcha_code:%s", // 参数为 uuid
|
||||
STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user