优化druid监控

This commit is contained in:
Dftre 2025-01-11 01:32:21 +08:00
parent 50d9199f53
commit c18ed644f4
5 changed files with 22 additions and 76 deletions

View File

@ -15,8 +15,6 @@ spring:
# url: jdbc:postgresql://127.0.0.1/ry # url: jdbc:postgresql://127.0.0.1/ry
# username: postgres # username: postgres
# password: 123456 # password: 123456
# filters: stat,wall
# connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 从库数据源 # 从库数据源
# SLAVE: # SLAVE:
# url: jdbc:mysql://127.0.0.1/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://127.0.0.1/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
@ -46,41 +44,31 @@ spring:
testWhileIdle: true testWhileIdle: true
testOnBorrow: false testOnBorrow: false
testOnReturn: false testOnReturn: false
# 配置监控统计拦截的filters # 配置监控统计拦截的filters stat=>监控统计 wall=>防SQL注入 slf4j log4j2=>日志记录
filters: stat,wall filters: stat,wall,slf4j,log4j2
# 通过connectProperties属性来打开mergeSql功能慢SQL记录 # 通过connectProperties属性来打开mergeSql功能慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
webStatFilter: # 配置spring监控的匹配类
aop-patterns: com.ruoyi.*.service.*,com.ruoyi.*.mapper.*
# Web应用 和 URL监控 配置
web-stat-filter:
enabled: true enabled: true
url-pattern: /* url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
sessionStatEnable: true session-stat-enable: false # 是否开启session统计功能
statViewServlet: # 监控视图配置
stat-view-servlet:
enabled: true enabled: true
url-pattern: /druid/* url-pattern: /druid/*+
allow: 127.0.0.1 reset-enable: true # 是否可以重置日志
deny: "" login-username: ruoyi # 用户名
reset-enable: false login-password: 123456 # 密码
login-username: ruoyi allow: "" # IP白名单 (没有配置或者为空,则允许所有访问)
login-password: 123456 deny: "" # IP黑名单 (存在共同时deny优先于allow)
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
enabled: true
config:
multi-statement-allow: true
select-allow: true
stat-view-servlet:
enabled: true
# 是否开启分布式事务如不开启请删除atomikos插件否则atomikos相关驱动虽不生效但仍会启动 # 是否开启分布式事务如不开启请删除atomikos插件否则atomikos相关驱动虽不生效但仍会启动
atomikos: atomikos:

View File

@ -9,14 +9,11 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties; import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.support.jakarta.StatViewServlet;
import com.alibaba.druid.support.jakarta.WebStatFilter;
import com.alibaba.druid.util.Utils; import com.alibaba.druid.util.Utils;
import jakarta.annotation.PreDestroy; import jakarta.annotation.PreDestroy;
@ -47,7 +44,7 @@ public class DruidConfig {
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Bean @Bean
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) { FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) {
// 获取web监控页面的参数 // 获取web监控页面的参数
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
// 提取common.js的配置路径 // 提取common.js的配置路径
@ -84,29 +81,6 @@ public class DruidConfig {
return registrationBean; return registrationBean;
} }
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.webStatFilter.enabled", havingValue = "true")
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
filterRegistrationBean.addInitParameter("sessionStatEnable", "true");
return filterRegistrationBean;
}
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
public ServletRegistrationBean statViewServlet(DruidStatProperties properties) {
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
servletRegistrationBean.addInitParameter("loginUsername", config.getLoginUsername());
servletRegistrationBean.addInitParameter("loginPassword", config.getLoginPassword());
servletRegistrationBean.addInitParameter("allow", config.getAllow());
servletRegistrationBean.addInitParameter("deny", config.getDeny());
servletRegistrationBean.addInitParameter("resetEnable", String.valueOf(config.getResetEnable()));
return servletRegistrationBean;
}
public List<DruidDataSource> getDruidDataSources() { public List<DruidDataSource> getDruidDataSources() {
return druidDataSources; return druidDataSources;
} }

View File

@ -19,8 +19,6 @@ public class DynamicDataSourceProperties {
private Map<String, DataSourceProperties> datasource; private Map<String, DataSourceProperties> datasource;
private String primary; private String primary;
public Properties build(DataSourceProperties dataSourceProperties) { public Properties build(DataSourceProperties dataSourceProperties) {
Properties prop = new Properties(); Properties prop = new Properties();
DruidProperties druidProperties = SpringUtils.getBean(DruidProperties.class); DruidProperties druidProperties = SpringUtils.getBean(DruidProperties.class);
@ -39,10 +37,9 @@ public class DynamicDataSourceProperties {
prop.setProperty("testWhileIdle", String.valueOf(druidProperties.isTestWhileIdle())); prop.setProperty("testWhileIdle", String.valueOf(druidProperties.isTestWhileIdle()));
prop.setProperty("testOnBorrow", String.valueOf(druidProperties.isTestOnBorrow())); prop.setProperty("testOnBorrow", String.valueOf(druidProperties.isTestOnBorrow()));
prop.setProperty("testOnReturn", String.valueOf(druidProperties.isTestOnReturn())); prop.setProperty("testOnReturn", String.valueOf(druidProperties.isTestOnReturn()));
// 添加过滤器配置 // 修改filters配置确保spring在最前面
prop.setProperty("filters", "stat,wall"); prop.setProperty("filters", SpringUtils.getRequiredProperty("spring.datasource.druid.filters"));
prop.setProperty("connectionProperties", "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000"); prop.setProperty("connectionProperties", SpringUtils.getRequiredProperty("spring.datasource.druid.connectionProperties"));
prop.setProperty("proxyFilters", ""); // 确保不会覆盖默认的过滤器
return prop; return prop;
} }
@ -84,17 +81,6 @@ public class DynamicDataSourceProperties {
if (prop.getProperty("testOnReturn") != null) { if (prop.getProperty("testOnReturn") != null) {
dataSource.setTestOnReturn(Boolean.parseBoolean(prop.getProperty("testOnReturn"))); dataSource.setTestOnReturn(Boolean.parseBoolean(prop.getProperty("testOnReturn")));
} }
// 添加监控配置
if (prop.getProperty("filters") != null) {
try {
dataSource.setFilters(prop.getProperty("filters"));
} catch (Exception e) {
e.printStackTrace();
}
}
if (prop.getProperty("connectionProperties") != null) {
dataSource.setConnectionProperties(prop.getProperty("connectionProperties"));
}
// 确保过滤器配置生效 // 确保过滤器配置生效
try { try {
if (prop.getProperty("filters") != null) { if (prop.getProperty("filters") != null) {

View File

@ -30,9 +30,7 @@ public class DataSourceCreate implements CreateDataSource {
dataSource.setConnectProperties(prop); dataSource.setConnectProperties(prop);
properties.setProperties(dataSource, prop); properties.setProperties(dataSource, prop);
// 确保监控和防火墙功能开启
try { try {
dataSource.setFilters("stat,wall");
dataSource.init(); dataSource.init();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("初始化数据源失败", e); throw new RuntimeException("初始化数据源失败", e);

View File

@ -220,7 +220,7 @@ public class MessageSystemController extends BaseController
*/ */
@Operation(summary = "查询模版签名") @Operation(summary = "查询模版签名")
@GetMapping("/selecTemplates") @GetMapping("/selecTemplates")
public R selecTemplates() { public R<List<MessageTemplate>> selecTemplates() {
List<MessageTemplate> templates= messageSystemService.selecTemplates(); List<MessageTemplate> templates= messageSystemService.selecTemplates();
return R.ok(templates); return R.ok(templates);
} }