Druid-监控

本文详细介绍Druid数据库连接池的监控配置与功能,包括如何使用StatFilter进行SQL监控统计,慢SQL记录,连接泄漏监测等。同时,介绍了StatViewServlet的配置方法,以及如何与Spring框架结合使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Druid的源码

Druid为alibaba的开源项目,托管在github上。传送门在此 : https://github.com/alibaba/druid

Druid Filter介绍

Druid提供的扩展可以通过查看 druid-xxx.jar!/META-INF/druid-filter.properties 。该文件记录的Filter的对应的别名

druid.filters.default=com.alibaba.druid.filter.stat.StatFilter
druid.filters.stat=com.alibaba.druid.filter.stat.StatFilter
druid.filters.mergeStat=com.alibaba.druid.filter.stat.MergeStatFilter
druid.filters.counter=com.alibaba.druid.filter.stat.StatFilter
druid.filters.encoding=com.alibaba.druid.filter.encoding.EncodingConvertFilter
druid.filters.log4j=com.alibaba.druid.filter.logging.Log4jFilter
druid.filters.log4j2=com.alibaba.druid.filter.logging.Log4j2Filter
druid.filters.slf4j=com.alibaba.druid.filter.logging.Slf4jLogFilter
druid.filters.commonlogging=com.alibaba.druid.filter.logging.CommonsLogFilter
druid.filters.commonLogging=com.alibaba.druid.filter.logging.CommonsLogFilter
druid.filters.wall=com.alibaba.druid.wall.WallFilter
druid.filters.config=com.alibaba.druid.filter.config.ConfigFilter

开始前注意点

以下为Spring-Maven项目的配置

StatFilter 监控统计功能

在xml中配置添加Filter

需要在 Druid 数据库连接池的对应的bean进行配置。(com.alibaba.druid.pool.DruidDataSource) 。

1. 别名配置

可以通过 filters 属性进行配置

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		destroy-method="close" init-method="init">
		<!-- 配置StatFilter -->
		<property name="filters" value="stat" />
		<!--
		.... 其他相关的属性配置
		-->
</bean>

2. 组合配置

filters 属性可以配置多值

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		destroy-method="close" init-method="init">
		<!-- 配置StatFilter -->
		<property name="filters" value="stat,log4j" />
		<!--
		.... 其他相关的属性配置
		-->
</bean>

3. ProxyFilters属性配置

当需要对Filter进行特定的属性值的配置的时候,可以使用该方式。

	<!-- stat Filter Bean配置 -->
	<bean id="stat_filter" class="com.alibaba.druid.filter.stat.StatFilter">
		<!-- slowSqlMillis用来配置SQL慢的标准,执行时间超过slowSqlMillis就是慢
		slowSqlMillis的缺省值为3000,也就是3秒
		logSlowSql 表示通过日志输出执行慢的SQL
		slowSqlMillis属性也可以通过connectProperties来配置
		<property name="connectionProperties" value="druid.stat.slowSqlMillis=5000">
		 -->
		<property name="slowSqlMillis" value="10000"></property>
		<property name="logSlowSql" value="true"></property>
		<!-- 合并多个DruidDataSource的监控数据 
		<property name="useGlobalDataSourceStat" value="true"></property>
		-->
		<!-- 合并SQL  -->
		<property name="mergeSql" value="true"></property>
	</bean>


	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		destroy-method="close" init-method="init">
		
		<!-- proxyFilters 配置Stat -->
		<property name="filters" value="log4j"></property>
		
		<property name="proxyFilters">
			<list>
				<ref bean="stat_filter" />
			</list>
		</property>
		<!--
		.... 其他相关的属性配置
		-->
	 </bean>

StatFilter的相关属性

1. mergeStat 合并SQL

在程序执行中,对于没有参数化的sql,StatFilter的统计效果并不是很好,比如说,以下的3条sql会被统计为3条。然后,实际上以下sql语句在统计的时候是1条。

select * from student where stuId = 2001
select * from student where stuId = 2002
select * from student where stuId = 2003

StatFilter提供了合并的功能。如果设置mergeStat属性为true,则以上的语句都会被合并为
select * from student where stuId = ?

  • 使用StateFilter的mergeStat属性配置

    <bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
    	<property name="mergeSql" value="true" />
    </bean>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    	init-method="init" destroy-method="close">
    	... ...
    	<property name="proxyFilters">
    		<list>
    			<ref bean="stat-filter" />
    		</list>
    	</property>
    </bean>
    
  • 直接修改StatFilter配置为mergeStatFilter

    	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    		destroy-method="close" init-method="init">
    		<!-- 配置StatFilter -->
    		<property name="filters" value="mergeStat" />
    		<!--
    		.... 其他相关的属性配置
    		-->
    </bean>
    
  • 通过connectionProperties属性进行配置

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    		destroy-method="close" init-method="init">
    		<!-- 配置StatFilter -->
    		<property name="filters" value="stat" />
    		<property name="connectionProperties"
    		value="druid.stat.mergeSql=true" />
    		<!--
    		.... 其他相关的属性配置
    		-->
    </bean>
    
  • 通过添加JVM的参数配置

    -Druid.stat.mergeSql=true
    
  • 在druid-0.2.17版本之后,sql合并支持tddl,能够对分表进行合并

2. 慢Sql记录

StatFilter属性slowSqlMillis用来配置SQL慢的标准,执行时间超过slowSqlMillis的就是慢。slowSqlMillis的缺省值为3000,也就是3秒

<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
	<property name="slowSqlMillis" value="10000" />
	<property name="logSlowSql" value="true" />
</bean>

在上面的配置中,slowSqlMillis被修改为10秒,并且通过日志输出执行慢的SQL。

slowSqlMillis属性也可以通过connectProperties来配置,例如:

  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
  	<property name="filters" value="stat" />
  	<property name="connectionProperties" value="druid.stat.slowSqlMillis=5000" />
  </bean>

3. 合并多个DruidDataSource的监控数据

缺省多个DruidDataSource的监控数据是各自独立的,在Druid-0.2.17版本之后,支持配置公用监控数据,配置参数为useGlobalDataSourceStat。例如:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
	<property name="useGlobalDataSourceStat" value="true" />
</bean>

或者通过jvm启动参数来指定,例如:
-Ddruid.useGlobalDataSourceStat=true
全部使用jvm启动参数来配置,可以这样:
-Ddruid.filters=mergeStat -Ddruid.useGlobalDataSourceStat=true

4. 连接泄漏监测

当程序存在缺陷时,申请的连接忘记关闭,这时候,就存在连接泄漏了。Druid提供了RemoveAbandanded相关配置,用来关闭长时间不使用的连接。例如:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
 
  	<property name="removeAbandoned" value="true" /> <!-- 打开removeAbandoned功能 -->
  	<property name="removeAbandonedTimeout" value="1800" /> <!-- 1800秒,也就是30分钟 -->
  	<property name="logAbandoned" value="true" /> <!-- 关闭abanded连接时输出错误日志 -->
 
  </bean>

配置removeAbandoned对性能会有一些影响,建议怀疑存在泄漏之后再打开。在上面的配置中,如果连接超过30分钟未关闭,就会被强行回收,并且日志记录连接申请时的调用堆栈。

5. 保存DruidDataSource的监控记录

DruidDataSource有一个属性timeBetweenLogStatsMillis,配置timeBetweenLogStatsMillis>0之后,DruidDataSource会定期把监控数据输出到日志中。

  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
	  	<property name="timeBetweenLogStatsMillis" value="300000" />
  </bean>

或者通过jvm启动参数来指定,例如:
-Ddruid.timeBetweenLogStatsMillis=300000

6. 定制StatLogger

DruidDataSource是通过com.alibaba.druid.pool.DruidDataSourceStatLoggerImpl.DruidDataSourceStatLoggerImpl来实现输入监控数据到日志的,你可以自定义一个StatLogger,例如:

Java代码

  import com.alibaba.druid.pool.DruidDataSourceStatLoggerAdapter;
  import com.alibaba.druid.pool.DruidDataSourceStatLogger ;
  public class MyStatLogger extends DruidDataSourceStatLoggerAdapter implements DruidDataSourceStatLogger {
  	... ...
  }

配置

  <bean id="myStatLogger" class="com.mycompany.MyStatLogger">
  	... ...
  </bean>
  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
  	... ...
  	<property name="statLogger" ref="myStatLogger" />
  	... ...
  </bean>

StatViewServlet配置

Druid内置提供了一个StatViewServlet用于展示Druid的统计信息。
这个StatViewServlet的用途包括:

  • 提供监控信息展示的html页面
  • 提供监控信息的JSON API

注意:使用StatViewServlet,建议使用druid 0.2.6以上版本。

配置Servlet

StatViewServlet是一个标准的javax.servlet.http.HttpServlet,需要配置在你web应用中的WEB-INF/web.xml中。

<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>

根据配置中的url-pattern来访问内置监控页面,如果是上面的配置,内置监控页面的首页是/druid/index.html

例如:
http://110.76.43.235:9000/druid/index.html
http://110.76.43.235:8080/mini-web/druid/index.html

配置监控页面访问密码

需要配置Servlet的 loginUsername 和 loginPassword这两个初始参数。
具体可以参考: 为Druid监控配置访问权限(配置访问监控信息的用户与密码)
示例如下:

	<!-- 配置 Druid 监控信息显示页面 -->  
	<servlet>  
	    <servlet-name>DruidStatView</servlet-name>  
	    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>  
	    <init-param>  
			<!-- 允许清空统计数据 -->  
			<param-name>resetEnable</param-name>  
			<param-value>true</param-value>  
	    </init-param>  
	    <init-param>  
			<!-- 用户名 -->  
			<param-name>loginUsername</param-name>  
			<param-value>druid</param-value>  
	    </init-param>  
	    <init-param>  
			<!-- 密码 -->  
			<param-name>loginPassword</param-name>  
			<param-value>druid</param-value>  
	    </init-param>  
	</servlet>  
	<servlet-mapping>  
	    <servlet-name>DruidStatView</servlet-name>  
	    <url-pattern>/druid/*</url-pattern>  
	</servlet-mapping> 

配置allow和deny

StatViewSerlvet展示出来的监控信息比较敏感,是系统运行的内部情况,如果你需要做访问控制,可以配置allow和deny这两个参数。比如:

  <servlet>
      <servlet-name>DruidStatView</servlet-name>
      <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
  	<init-param>
  		<param-name>allow</param-name>
  		<param-value>128.242.127.1/24,128.242.128.1</param-value>
  	</init-param>
  	<init-param>
  		<param-name>deny</param-name>
  		<param-value>128.242.127.4</param-value>
  	</init-param>
  </servlet>
  • 判断规则

    deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝。
    如果allow没有配置或者为空,则允许所有访问

  • ip配置规则
    配置的格式

      <IP>
      或者
      <IP>/<SUB_NET_MASK_size>
    

    其中

    128.242.127.1/24
    

    24表示,前面24位是子网掩码,比对的时候,前面24位相同就匹配。

  • 不支持IPV6
    由于匹配规则不支持IPV6,配置了allow或者deny之后,会导致IPV6无法访问。

配置resetEnable

在StatViewSerlvet输出的html页面中,有一个功能是Reset All,执行这个操作之后,会导致所有计数器清零,重新计数。你可以通过配置参数关闭它。

  <servlet>
      <servlet-name>DruidStatView</servlet-name>
      <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
  	<init-param>
  		<param-name>resetEnable</param-name>
  		<param-value>false</param-value>
  	</init-param>
  </servlet>

配置Druid和Spring的关联监控配置

Druid提供了Spring和Jdbc的关联监控。

按类型拦截配置

  <bean id="druid-stat-interceptor"
  	class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
  </bean>
  
  <bean id="druid-type-proxyCreator" class="com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator">
  	<!-- 所有ABCInterface的派生类被拦截监控  -->
  	<property name="targetBeanType" value="xxxx.ABCInterface" />
  	<property name="interceptorNames">
  		<list>
  			<value>druid-stat-interceptor</value>
  		</list>
  	</property>
  </bean>

方法名正则匹配拦截配置

  <bean id="druid-stat-interceptor"
  	class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
  </bean>

<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"
	scope="prototype">
	<property name="patterns">
		<list>
			<value>com.mycompany.service.*</value>
			<value>com.mycompany.dao.*</value>
		</list>
	</property>
</bean>

<aop:config>
	<aop:advisor advice-ref="druid-stat-interceptor"
		pointcut-ref="druid-stat-pointcut" />
</aop:config>

有些情况下,可能你需要配置proxy-target-class,例如:

<aop:config proxy-target-class="true">
	<aop:advisor advice-ref="druid-stat-interceptor"
		pointcut-ref="druid-stat-pointcut" />
</aop:config>

按照BeanId来拦截配置

  <bean id="druid-stat-interceptor"
  	class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
  </bean>

<bean
	class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
	<property name="proxyTargetClass" value="true" />
	<property name="beanNames">
		<list>
			<!-- 这里配置需要拦截的bean id列表 -->
			<value>xxx-dao</value>
			<value>xxx-service</value>
		</list>
	</property>
	<property name="interceptorNames">
		<list>
			<value>druid-stat-interceptor</value>
		</list>
	</property>
</bean>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值