feat(cache): 添加 Caffeine缓存支持并优化日志处理
- 在应用配置中添加 Caffeine 缓存配置 - 新增 CaffeineConfig 类用于缓存管理 - 在 Log 实体中添加 userAgent 字段保存原始用户代理字符串 - 优化 LogAspect 中的用户代理解析逻辑,增加缓存支持 - 更新数据库表结构,在 log 表中添加 user_agent 列
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -57,6 +57,7 @@
|
|||||||
|
|
||||||
<!-- 微信 jdk -->
|
<!-- 微信 jdk -->
|
||||||
<weixin-java.version>4.5.5.B</weixin-java.version>
|
<weixin-java.version>4.5.5.B</weixin-java.version>
|
||||||
|
<caffeine.version>2.9.3</caffeine.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -232,6 +233,12 @@
|
|||||||
<version>${weixin-java.version}</version>
|
<version>${weixin-java.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
<version>${caffeine.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ CREATE TABLE `sys_log` (
|
|||||||
`browser` varchar(100) DEFAULT NULL COMMENT '浏览器',
|
`browser` varchar(100) DEFAULT NULL COMMENT '浏览器',
|
||||||
`browser_version` varchar(100) DEFAULT NULL COMMENT '浏览器版本',
|
`browser_version` varchar(100) DEFAULT NULL COMMENT '浏览器版本',
|
||||||
`os` varchar(100) DEFAULT NULL COMMENT '终端系统',
|
`os` varchar(100) DEFAULT NULL COMMENT '终端系统',
|
||||||
|
`user_agent` varchar(255) DEFAULT NULL COMMENT '原生的用户代理字符串',
|
||||||
`create_by` bigint DEFAULT NULL COMMENT '创建人ID',
|
`create_by` bigint DEFAULT NULL COMMENT '创建人ID',
|
||||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '逻辑删除标识(1-已删除 0-未删除)',
|
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '逻辑删除标识(1-已删除 0-未删除)',
|
||||||
|
|||||||
@@ -416,6 +416,7 @@ CREATE TABLE `sys_log` (
|
|||||||
`browser` varchar(100) DEFAULT NULL COMMENT '浏览器',
|
`browser` varchar(100) DEFAULT NULL COMMENT '浏览器',
|
||||||
`browser_version` varchar(100) DEFAULT NULL COMMENT '浏览器版本',
|
`browser_version` varchar(100) DEFAULT NULL COMMENT '浏览器版本',
|
||||||
`os` varchar(100) DEFAULT NULL COMMENT '终端系统',
|
`os` varchar(100) DEFAULT NULL COMMENT '终端系统',
|
||||||
|
`user_agent` varchar(255) DEFAULT NULL COMMENT '原生的用户代理字符串',
|
||||||
`create_by` bigint DEFAULT NULL COMMENT '创建人ID',
|
`create_by` bigint DEFAULT NULL COMMENT '创建人ID',
|
||||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '逻辑删除标识(1-已删除 0-未删除)',
|
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '逻辑删除标识(1-已删除 0-未删除)',
|
||||||
|
|||||||
37
src/main/java/com/youlai/boot/config/CaffeineConfig.java
Normal file
37
src/main/java/com/youlai/boot/config/CaffeineConfig.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package com.youlai.boot.config;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* caffeine缓存配置
|
||||||
|
*
|
||||||
|
* @author Theo
|
||||||
|
* @since 2025-01-22 17:40:23
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
public class CaffeineConfig {
|
||||||
|
|
||||||
|
@Value("${spring.cache.caffeine.spec}")
|
||||||
|
private String caffeineSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存管理器
|
||||||
|
*
|
||||||
|
* @return CacheManager 缓存管理器
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CacheManager cacheManager() {
|
||||||
|
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
|
||||||
|
Caffeine<Object, Object> caffeineBuilder = Caffeine.from(caffeineSpec);
|
||||||
|
caffeineCacheManager.setCaffeine(caffeineBuilder);
|
||||||
|
return caffeineCacheManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -3,9 +3,11 @@ package com.youlai.boot.core.aspect;
|
|||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.date.TimeInterval;
|
import cn.hutool.core.date.TimeInterval;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
import cn.hutool.http.useragent.UserAgent;
|
import cn.hutool.http.useragent.UserAgent;
|
||||||
import cn.hutool.http.useragent.UserAgentUtil;
|
import cn.hutool.http.useragent.UserAgentUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.alibaba.excel.util.StringUtils;
|
||||||
import com.aliyun.oss.HttpMethod;
|
import com.aliyun.oss.HttpMethod;
|
||||||
import com.youlai.boot.common.enums.LogModuleEnum;
|
import com.youlai.boot.common.enums.LogModuleEnum;
|
||||||
import com.youlai.boot.common.util.IPUtils;
|
import com.youlai.boot.common.util.IPUtils;
|
||||||
@@ -21,6 +23,7 @@ import org.aspectj.lang.annotation.AfterReturning;
|
|||||||
import org.aspectj.lang.annotation.AfterThrowing;
|
import org.aspectj.lang.annotation.AfterThrowing;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
@@ -37,14 +40,18 @@ import java.util.Objects;
|
|||||||
* @author Ray.Hao
|
* @author Ray.Hao
|
||||||
* @since 2024/6/25
|
* @since 2024/6/25
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
|
||||||
public class LogAspect {
|
public class LogAspect {
|
||||||
private final LogService logService;
|
private final LogService logService;
|
||||||
private final HttpServletRequest request;
|
private final HttpServletRequest request;
|
||||||
|
private final CacheManager cacheManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切点
|
||||||
|
*/
|
||||||
@Pointcut("@annotation(com.youlai.boot.common.annotation.Log)")
|
@Pointcut("@annotation(com.youlai.boot.common.annotation.Log)")
|
||||||
public void logPointcut() {
|
public void logPointcut() {
|
||||||
}
|
}
|
||||||
@@ -72,7 +79,12 @@ public class LogAspect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保持日志
|
* 保存日志
|
||||||
|
*
|
||||||
|
* @param joinPoint 切点
|
||||||
|
* @param e 异常
|
||||||
|
* @param jsonResult 响应结果
|
||||||
|
* @param logAnnotation 日志注解
|
||||||
*/
|
*/
|
||||||
private void saveLog(final JoinPoint joinPoint, final Exception e, Object jsonResult, com.youlai.boot.common.annotation.Log logAnnotation) {
|
private void saveLog(final JoinPoint joinPoint, final Exception e, Object jsonResult, com.youlai.boot.common.annotation.Log logAnnotation) {
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
@@ -120,8 +132,9 @@ public class LogAspect {
|
|||||||
log.setExecutionTime(executionTime);
|
log.setExecutionTime(executionTime);
|
||||||
// 获取浏览器和终端系统信息
|
// 获取浏览器和终端系统信息
|
||||||
String userAgentString = request.getHeader("User-Agent");
|
String userAgentString = request.getHeader("User-Agent");
|
||||||
UserAgent userAgent = UserAgentUtil.parse(userAgentString);
|
log.setUserAgent(userAgentString);
|
||||||
if(Objects.nonNull(userAgent)) {
|
UserAgent userAgent = resolveUserAgent(userAgentString);
|
||||||
|
if (Objects.nonNull(userAgent)) {
|
||||||
// 系统信息
|
// 系统信息
|
||||||
log.setOs(userAgent.getOs().getName());
|
log.setOs(userAgent.getOs().getName());
|
||||||
// 浏览器信息
|
// 浏览器信息
|
||||||
@@ -193,4 +206,27 @@ public class LogAspect {
|
|||||||
return obj instanceof MultipartFile || obj instanceof HttpServletRequest || obj instanceof HttpServletResponse;
|
return obj instanceof MultipartFile || obj instanceof HttpServletRequest || obj instanceof HttpServletResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析UserAgent
|
||||||
|
*
|
||||||
|
* @param userAgentString UserAgent字符串
|
||||||
|
* @return UserAgent
|
||||||
|
*/
|
||||||
|
public UserAgent resolveUserAgent(String userAgentString) {
|
||||||
|
if (StringUtils.isBlank(userAgentString)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 给userAgentStringMD5加密一次防止过长
|
||||||
|
String userAgentStringMD5 = DigestUtil.md5Hex(userAgentString);
|
||||||
|
//判断是否命中缓存
|
||||||
|
UserAgent userAgent = Objects.requireNonNull(cacheManager.getCache("userAgent")).get(userAgentStringMD5, UserAgent.class);
|
||||||
|
if (userAgent != null) {
|
||||||
|
return userAgent;
|
||||||
|
}
|
||||||
|
userAgent = UserAgentUtil.parse(userAgentString);
|
||||||
|
Objects.requireNonNull(cacheManager.getCache("userAgent")).put(userAgentStringMD5, userAgent);
|
||||||
|
return userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.youlai.boot.system.controller;
|
package com.youlai.boot.system.controller;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.alibaba.excel.ExcelWriter;
|
import com.alibaba.excel.ExcelWriter;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
@@ -63,6 +64,7 @@ public class UserController {
|
|||||||
@Valid UserPageQuery queryParams
|
@Valid UserPageQuery queryParams
|
||||||
) {
|
) {
|
||||||
IPage<UserPageVO> result = userService.getUserPage(queryParams);
|
IPage<UserPageVO> result = userService.getUserPage(queryParams);
|
||||||
|
|
||||||
return PageResult.success(result);
|
return PageResult.success(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.youlai.boot.system.model.entity;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.youlai.boot.common.enums.LogModuleEnum;
|
import com.youlai.boot.common.enums.LogModuleEnum;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@@ -87,6 +86,11 @@ public class Log implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String os;
|
private String os;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原生的用户代理字符串
|
||||||
|
*/
|
||||||
|
private String userAgent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行时间(毫秒)
|
* 执行时间(毫秒)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ spring:
|
|||||||
time-to-live: 3600000
|
time-to-live: 3600000
|
||||||
# 缓存null值,防止缓存穿透
|
# 缓存null值,防止缓存穿透
|
||||||
cache-null-values: true
|
cache-null-values: true
|
||||||
|
caffeine:
|
||||||
|
spec: initialCapacity=50,maximumSize=1000,expireAfterWrite=600s
|
||||||
# 邮件配置
|
# 邮件配置
|
||||||
mail:
|
mail:
|
||||||
host: smtp.youlai.tech
|
host: smtp.youlai.tech
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ spring:
|
|||||||
enable: true
|
enable: true
|
||||||
# 邮件发送者
|
# 邮件发送者
|
||||||
from: youlaitech@163.com
|
from: youlaitech@163.com
|
||||||
|
caffeine:
|
||||||
|
spec: initialCapacity=50,maximumSize=500,expireAfterWrite=3600s
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
mapper-locations: classpath*:/mapper/**/*.xml
|
mapper-locations: classpath*:/mapper/**/*.xml
|
||||||
global-config:
|
global-config:
|
||||||
|
|||||||
Reference in New Issue
Block a user