Druid的简介
Druid是一个非常优秀的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。
Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
Druid是一个JDBC组件,它包括三个部分:
基于Filter-Chain模式的插件体系。
DruidDataSource 高效可管理的数据库连接池。
SQLParser
Druid的功能
兼容DBCP
Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。从DBCP迁移到Druid,只需要修改数据源的实现类就可以了。
强大的监控特性
Druid内置了一个功能强大的StatFilter插件可以监控数据库访问性能,可以清楚知道连接池和SQL的工作情况。
监控SQL的执行时间、ResultSet持有时间、返回行数、更新行数、错误次数、错误堆栈信息。
SQL执行的耗时区间分布。什么是耗时区间分布呢?比如说,某个SQL执行了1000次,其中0-1毫秒区间50次,1-10毫秒800次,10-100毫秒100次,100-1000毫秒30次,1-10秒15次,10秒以上5次。通过耗时区间分布,能够非常清楚知道SQL的执行耗时情况。
监控连接池的物理连接创建和销毁次数、逻辑连接的申请和关闭次数、非空等待次数、PSCache命中率等。
数据库密码加密
直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
SQL执行日志
Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
扩展JDBC
如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。
Druid在DruidDataSourc和ProxyDriver上提供了Filter-Chain模式的扩展API,类似Serlvet的Filter,配置Filter拦截JDBC的方法调用。
SQLParser
SQL Parser是Druid的一个重要组成部分,它提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。
简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如防御SQL注入(WallFilter)、合并统计没有参数化的SQL(StatFilter的mergeSql)、SQL格式化、分库分表。
http://blog.csdn.net/qq_30444003/article/details/50795116
Druid的配置详解
配置 缺省值 说明
name 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。如果没有配置,将会生成一个名字,格式是:”DataSource-” + System.identityHashCode(this). 另外配置此属性至少在1.0.5版本中是不起作用的,强行设置name会出错。详情-点此处。
url 连接数据库的url,不同数据库不一样。例如:
mysql : jdbc:mysql://10.20.153.104:3306/druid2
oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
username 连接数据库的用户名
password 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里
driverClassName 根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName
initialSize 0 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive 8 最大连接池数量
maxIdle 8 已经不再使用,配置了也没效果
minIdle 最小连接池数量
maxWait 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatements false 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
maxPoolPreparedStatementPerConnectionSize -1 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuery 用来检测连接是否有效的sql,要求是一个查询语句,常用select ‘x’。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
validationQueryTimeout 单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法
testOnBorrow true 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturn false 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testWhileIdle false 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
timeBetweenEvictionRunsMillis 1分钟(1.0.14) 有两个含义:
1) Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun 30分钟(1.0.14) 不再使用,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillis 连接保持空闲而不被驱逐的最长时间
connectionInitSqls 物理连接初始化的时候执行的sql
exceptionSorter 根据dbType自动识别 当数据库抛出一些不可恢复的异常时,抛弃连接
filters 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
监控统计用的filter:stat
日志用的filter:log4j
防御sql注入的filter:wall
proxyFilters 类型是List,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系
Druid源码
https://github.com/alibaba/druid/wiki
Druid常见问题
https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
项目实践
我们使用的是Spring boot + mybatis + Druid的架构
导入依赖包
<!-- 数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- Mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <!--Mybatis 分页插件 pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- Druid连接池包 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.25</version> </dependency>
配置数据源
目前Spring Boot中默认支持的连接池有dbcp,dbcp2, tomcat, hikari四种连接池。
由于Druid暂时不在Spring Bootz中的直接支持,故需要进行配置信息的定制:
新建配置类
package com.xiaolyuh.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "spring.datasource.druid") public class DruidDataSourceProperty { // 数据库配置 private String url; private String username; private String password; private String driverClassName; // 初始化大小,最小,最大 private int initialSize = 0; private int minIdle; private int maxActive = 8; // 配置获取连接等待超时的时间 private int maxWait; // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 private int timeBetweenEvictionRunsMillis = 1000 * 60; // 配置一个连接在池中最小生存的时间,单位是毫秒 private int minEvictableIdleTimeMillis = 1000 * 60 * 30; // 检测连接是否有效的sql private String validationQuery; private boolean testWhileIdle = false; private boolean testOnBorrow = true; private boolean testOnReturn = false; // PSCache Mysql下建议关闭 private boolean poolPreparedStatements = false; private int maxPoolPreparedStatementPerConnectionSize = - 1; // 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 private String filters; // 合并多个DruidDataSource的监控数据 private boolean useGlobalDataSourceStat = false; private String connectionProperties; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getDriverClassName() { return driverClassName; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public int getInitialSize() { return initialSize; } public void setInitialSize(int initialSize) { this.initialSize = initialSize; } public int getMinIdle() { return minIdle; } public void setMinIdle(int minIdle) { this.minIdle = minIdle; } public int getMaxActive() { return maxActive; } public void setMaxActive(int maxActive) { this.maxActive = maxActive; } public int getMaxWait() { return maxWait; } public void setMaxWait(int maxWait) { this.maxWait = maxWait; } public int getTimeBetweenEvictionRunsMillis() { return timeBetweenEvictionRunsMillis; } public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) { this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; } public int getMinEvictableIdleTimeMillis() { return minEvictableIdleTimeMillis; } public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) { this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; } public String getValidationQuery() { return validationQuery; } public void setValidationQuery(String validationQuery) { this.validationQuery = validationQuery; } public boolean isTestWhileIdle() { return testWhileIdle; } public void setTestWhileIdle(boolean testWhileIdle) { this.testWhileIdle = testWhileIdle; } public boolean isTestOnBorrow() { return testOnBorrow; } public void setTestOnBorrow(boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; } public boolean isTestOnReturn() { return testOnReturn; } public void setTestOnReturn(boolean testOnReturn) { this.testOnReturn = testOnReturn; } public boolean isPoolPreparedStatements() { return poolPreparedStatements; } public void setPoolPreparedStatements(boolean poolPreparedStatements) { this.poolPreparedStatements = poolPreparedStatements; } public int getMaxPoolPreparedStatementPerConnectionSize() { return maxPoolPreparedStatementPerConnectionSize; } public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) { this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize; } public String getFilters() { return filters; } public void setFilters(String filters) { this.filters = filters; } public boolean isUseGlobalDataSourceStat() { return useGlobalDataSourceStat; } public void setUseGlobalDataSourceStat(boolean useGlobalDataSourceStat) { this.useGlobalDataSourceStat = useGlobalDataSourceStat; } public String getConnectionProperties() { return connectionProperties; } public void setConnectionProperties(String connectionProperties) { this.connectionProperties = connectionProperties; } }
该配置类我们采用Spring boot推荐的安全配置方式,使用@ConfigurationProperties注解,声明该类是一个配置类,并指定配置前缀。
配置连接池
package com.xiaolyuh.config; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; @Configuration @ConditionalOnClass(com.alibaba.druid.pool.DruidDataSource.class) @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.alibaba.druid.pool.DruidDataSource", matchIfMissing = true) @ServletComponentScan("com.xiaolyuh.filters") public class DruidDataSourceConfig { private Logger logger = LoggerFactory.getLogger(DruidDataSourceConfig.class); @Autowired private DruidDataSourceProperty druidDataSourceProperty; @Bean //声明其为Bean实例 @Primary //在同样的DataSource中,首先使用被标注的DataSource public DataSource dataSource(){ DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(druidDataSourceProperty.getUrl()); datasource.setUsername(druidDataSourceProperty.getUsername()); datasource.setPassword(druidDataSourceProperty.getPassword()); datasource.setDriverClassName(druidDataSourceProperty.getDriverClassName()); datasource.setInitialSize(druidDataSourceProperty.getInitialSize()); datasource.setMinIdle(druidDataSourceProperty.getMinIdle()); datasource.setMaxActive(druidDataSourceProperty.getMaxActive()); // 配置获取连接等待超时的时间 datasource.setMaxWait(druidDataSourceProperty.getMaxWait()); // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 datasource.setTimeBetweenEvictionRunsMillis(druidDataSourceProperty.getTimeBetweenEvictionRunsMillis()); // 配置一个连接在池中最小生存的时间,单位是毫秒 datasource.setMinEvictableIdleTimeMillis(druidDataSourceProperty.getMinEvictableIdleTimeMillis()); datasource.setValidationQuery(druidDataSourceProperty.getValidationQuery()); datasource.setTestWhileIdle(druidDataSourceProperty.isTestWhileIdle()); datasource.setTestOnBorrow(druidDataSourceProperty.isTestOnBorrow()); datasource.setTestOnReturn(druidDataSourceProperty.isTestOnReturn()); datasource.setPoolPreparedStatements(druidDataSourceProperty.isPoolPreparedStatements()); datasource.setMaxPoolPreparedStatementPerConnectionSize(druidDataSourceProperty.getMaxPoolPreparedStatementPerConnectionSize()); datasource.setUseGlobalDataSourceStat(druidDataSourceProperty.isUseGlobalDataSourceStat()); try { datasource.setFilters(druidDataSourceProperty.getFilters()); } catch (SQLException e) { logger.error("druid configuration initialization filter", e); } datasource.setConnectionProperties(druidDataSourceProperty.getConnectionProperties()); return datasource; } // // 配置Druid监控的StatViewServlet和WebStatFilter // @Bean // public ServletRegistrationBean druidServlet() { // logger.info("init Druid Servlet Configuration "); // ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); // servletRegistrationBean.setServlet(new StatViewServlet()); // servletRegistrationBean.addUrlMappings("/druid/*"); // Map<String, String> initParameters = new HashMap<String, String>(); // initParameters.put("loginUsername", "admin");// 用户名 // initParameters.put("loginPassword", "admin");// 密码 // initParameters.put("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能 // initParameters.put("allow", ""); // IP白名单 (没有配置或者为空,则允许所有访问) // //initParameters.put("deny", "192.168.20.38");// IP黑名单 (存在共同时,deny优先于allow) // servletRegistrationBean.setInitParameters(initParameters); // return servletRegistrationBean; // } // // @Bean // public FilterRegistrationBean filterRegistrationBean() { // FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); // filterRegistrationBean.setFilter(new WebStatFilter()); // filterRegistrationBean.addUrlPatterns("/*"); // filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); // return filterRegistrationBean; // } }
该类被@Configuration标注,声明成配置类;DataSource对象被@Bean声明,为Spring容器所管理, @Primary表示这里定义的DataSource将覆盖其他来源的DataSource。
application.properties配置信息:
# 数据源配置 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.druid.url=jdbc:mysql://localhost:3306/ssb_test spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver spring.datasource.druid.username=root spring.datasource.druid.password=root # 初始化大小,最小,最大 spring.datasource.druid.initial-size=5 spring.datasource.druid.min-idle=5 spring.datasource.druid.max-active=20 # 配置获取连接等待超时的时间 spring.datasource.druid.max-wait=60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 spring.datasource.druid.time-between-eviction-runs-millis=60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 spring.datasource.druid.min-evictable-idle-time-millis=300000 #检测连接是否有效的sql spring.datasource.druid.validation-query=SELECT 'x' spring.datasource.druid.test-while-idle=true spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false # PSCache Mysql下建议关闭 spring.datasource.druid.pool-prepared-statements=false spring.datasource.druid.max-pool-prepared-statement-per-connection-size=-1 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 spring.datasource.druid.filters=stat,wall,log4j # 合并多个DruidDataSource的监控数据 spring.datasource.druid.use-global-data-source-stat=true spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 #mybatis #entity扫描的包名 mybatis.type-aliases-package=com.xiaolyuh.domain.model #Mapper.xml所在的位置 mybatis.mapper-locations=classpath*:/mybaits/*Mapper.xml #开启MyBatis的二级缓存 mybatis.configuration.cache-enabled=true #pagehelper pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql
到这里我们数据源就配置好了,写一个测试类我们可以查看数据源是否生效。
测试类
package com.xiaolyuh; import com.alibaba.fastjson.JSON; import com.xiaolyuh.config.DruidDataSourceProperty; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit4.SpringRunner; import javax.sql.DataSource; @RunWith(SpringRunner.class) @SpringBootTest public class DataSourceTests { @Autowired ApplicationContext applicationContext; @Autowired DruidDataSourceProperty druidDataSourceProperty; @Test public void testDataSource() throws Exception { // 获取配置的数据源 DataSource dataSource = applicationContext.getBean(DataSource.class); // 查看配置数据源信息 System.out.println(dataSource.getClass().getName()); System.out.println(JSON.toJSONString(druidDataSourceProperty)); } }
打印日志:
com.alibaba.druid.pool.DruidDataSource {"connectionProperties":"druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000","driverClassName":"com.mysql.jdbc.Driver","filters":"stat,wall,log4j","initialSize":5,"maxActive":20,"maxPoolPreparedStatementPerConnectionSize":-1,"maxWait":60000,"minEvictableIdleTimeMillis":300000,"minIdle":5,"password":"root","poolPreparedStatements":false,"testOnBorrow":false,"testOnReturn":false,"testWhileIdle":true,"timeBetweenEvictionRunsMillis":60000,"url":"jdbc:mysql://localhost:3306/ssb_test","useGlobalDataSourceStat":true,"username":"root","validationQuery":"SELECT 'x'"}
Druid监控的配置
下面我们来说一下Druid监控的配置:
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 spring.datasource.druid.filters=stat,wall,log4j
使用这个filter的配置,开启对监控的支持。属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
- 监控统计用的filter:stat
- 日志用的filter:log4j
- 防御sql注入的filter:wall
WebStatFilter和StatViewServlet配置
第一种方式使用@ServletComponentScan
这种配置监控的方式是使用了原生的servlet,filter方式,然后通过@ServletComponentScan进行启动扫描包的方式进行处理的,你会发现我们的servlet,filter根本没有任何的编码。
WebStatFilter:
package com.xiaolyuh.filters; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; import com.alibaba.druid.support.http.WebStatFilter; //最后在App.Java类上加上注解:@ServletComponentScan是的spring能够扫描到我们自己编写的servlet和filter。 // //注意不要忘记在 SpringBootSampleApplication.java 上添加 @ServletComponentScan 注解,不然就是404了。 // //然后启动项目后访问 http://127.0.0.1:8080/druid/index.html 即可查看数据源及SQL统计等。 @WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*", initParams = { @WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")//忽略资源 } ) public class DruidStatFilter extends WebStatFilter { }
StatViewServlet:
package com.xiaolyuh.filters; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import com.alibaba.druid.support.http.StatViewServlet; //最后在App.Java类上加上注解:@ServletComponentScan是的spring能够扫描到我们自己编写的servlet和filter。 // //注意不要忘记在 SpringBootSampleApplication.java 上添加 @ServletComponentScan 注解,不然就是404了。 // //然后启动项目后访问 http://127.0.0.1:8080/druid/index.html 即可查看数据源及SQL统计等。 @WebServlet(urlPatterns = "/druid/*", initParams = { @WebInitParam(name = "allow", value = "127.0.0.1,192.168.163.1"),// IP白名单(没有配置或者为空,则允许所有访问) @WebInitParam(name = "deny", value = "192.168.1.73"),// IP黑名单 (存在共同时,deny优先于allow) @WebInitParam(name = "loginUsername", value = "admin"),// 用户名 @WebInitParam(name = "loginPassword", value = "123456"),// 密码 @WebInitParam(name = "resetEnable", value = "false")// 禁用HTML页面上的“Reset All”功能 }) public class DruidStatViewServlet extends StatViewServlet { private static final long serialVersionUID = -2688872071445249539L; }
最后在App.Java类上加上注解:@ServletComponentScan是的spring能够扫描到我们自己编写的servlet和filter。
注意:不要忘记在 SpringBootSampleApplication.java 上添加 @ServletComponentScan 注解,不然就是404了。
这个配置就类似于在web.xml配置filter和servlet一样:
... <servlet> <servlet-name>DruidStatView</servlet-name> <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DruidStatView</servlet-name> <url-pattern>/druid/*</url-pattern> </servlet-mapping> ... <filter> <filter-name>DruidWebStatFilter</filter-name> <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class> <init-param> <param-name>exclusions</param-name> <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value> </init-param> </filter> <filter-mapping> <filter-name>DruidWebStatFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ...
第二种方式,直接在配置类中注册Bean
这种方式不使用使用@ServletComponentScan注解,在@Configuration配置类中使用代码注册Servlet。
// 配置Druid监控的StatViewServlet和WebStatFilter @Bean public ServletRegistrationBean druidServlet() { logger.info("init Druid Servlet Configuration "); ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); servletRegistrationBean.setServlet(new StatViewServlet()); servletRegistrationBean.addUrlMappings("/druid/*"); Map<String, String> initParameters = new HashMap<String, String>(); initParameters.put("loginUsername", "admin");// 用户名 initParameters.put("loginPassword", "admin");// 密码 initParameters.put("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能 initParameters.put("allow", ""); // IP白名单 (没有配置或者为空,则允许所有访问) //initParameters.put("deny", "192.168.20.38");// IP黑名单 (存在共同时,deny优先于allow) servletRegistrationBean.setInitParameters(initParameters); return servletRegistrationBean; } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new WebStatFilter()); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; }
打开监控界面
浏览器中输入:http://localhost/druid
输入用户名和密码,上面配置的。
源码
https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases
spring-boot-student-mybatis-druid 工程
————————————————
版权声明:本文为CSDN博主「xiaolyuh123」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaolyuh123/java/article/details/74099972