对于数据源,相信大家已经接触了不少了。比如c3p0、dhcp、proxool等,之后又发现使用tomcat-jdbc可以大大的提高性能。但是针对于我们的高并发的系统来说,总希望能找到一个性能更好、更稳定的产品来代替。在开源中国上偶然发现了很多公司都在使用Druid这个数据源,然后搜索了一些相关资料,有人提供了这几个数据源的性能测试报告,突然发现这个数据源以很好的性能已经被大家普遍使用了。于是自己也把项目中的jdbc数据源替换为Druid了,然后让测试人员帮忙压了一下系统,发现性能有所提高。于是就想深入的研究一下这个数据源了。其实很多项目都是JavaSE的,但是官网针对于JavaSE的项目又没有具体说明应该怎么使用其监控统计功能。于是自己就看了一下源码发现了有配置jmxUrl的地方,可以想想这个应该就是针对于远程监控项目的配置了。在这里我就整理一下自己的使用情况供以后的人员参考,如果有错误的地方,也请大牛指证,我也多学习学习。
首先说明一下大家都知道的几个地址吧,也省的访客来回搜索了。
正式版本下载地址:
Druid是一个开源项目,源码托管在github上: Druid 0.1.18之后版本都发布到maven中央仓库中,所以你只需要在项目的pom.xml中加上dependency就可以了。例如:[html]
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>${druid-version}</version>
- </dependency></span>
也可以选择 Maven仓库查找公共的仓库地址:
好了,废话也说了一大堆了。接下来说明一下怎么查看DruidDataSource的监控数据。
对于web项目,使用起来很方便,只需要在web.xml中配置一下DruidStatView就行了。其它的Druid已经帮我们都实现了。
1.Druid Monitor监控Java Web项目
先说明一下数据源的配置情况吧,例:
[html]
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd">
- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"
- destroy-method="close">
- <!-- 基本属性 url、user、password -->
- <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
- <property name="url" value="jdbc:oracle:thin:@192.168.102.93:1521:mydb1" />
- <property name="username" value="my_v31" />
- <property name="password" value="my_v31" />
- <!-- 配置初始化大小、最小、最大 -->
- <property name="initialSize" value="1" />
- <property name="minIdle" value="1" />
- <property name="maxActive" value="20" />
- <!-- 配置获取连接等待超时的时间 -->
- <property name="maxWait" value="60000" />
- <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
- <property name="timeBetweenEvictionRunsMillis" value="60000" />
- <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
- <property name="minEvictableIdleTimeMillis" value="300000" />
- <!--
- 用来检测连接是否有效的sql,要求是一个查询语句。
- 如果validationQuery为null,testOnBorrow、testOnReturn、
- testWhileIdle都不会其作用
- -->
- <property name="validationQuery" value="SELECT 1 FROM DUAL" />
- <property name="testWhileIdle" value="true" />
- <property name="testOnBorrow" value="false" />
- <property name="testOnReturn" value="false" />
- <!--
- 打开PSCache,并且指定每个连接上PSCache的大小
- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false
- -->
- <property name="poolPreparedStatements" value="true" />
- <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
- <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
- <property name="filters" value="stat,wall,log4j" />
- <!--
- 如果配置了proxyFilters,此配置可以不配置
- druid.stat.mergeSql=true 合并执行的相同sql,避免因为参数不同而统计多条sql语句
- druid.stat.slowSqlMillis=10000 用来配置SQL慢的标准,执行时间超过slowSqlMillis的就是慢
- <property name="connectionProperties" value="druid.stat.mergeSql=true;druid.stat.slowSqlMillis=10000" />
- -->
- <!-- 监控统计拦截的filters -->
- <!-- 并在filters属性中配置了log4j -->
- <property name="proxyFilters">
- <list>
- <ref bean="stat-filter" />
- <ref bean="log-filter" />
- </list>
- </property>
- </bean>
- <!-- 慢SQL记录-->
- <bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
- <property name="mergeSql" value="true" />
- <property name="slowSqlMillis" value="10000" />
- <property name="logSlowSql" value="true" />
- </bean>
- <bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter">
- <!-- <property name="resultSetLogEnabled" value="false" /> -->
- <!-- <property name="statementExecutableSqlLogEnable" value="true" /> -->
- </bean>
- <!-- 配置druid监控spring jdbc -->
- <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor" />
- <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">
- <property name="patterns">
- <list>
- <value>com.XXX.stat.service.*</value>
- <value>com.XXX.stat.dao.*</value>
- </list>
- </property>
- </bean>
- <aop:config proxy-target-class="true">
- <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
- </aop:config>
- </beans>
尽管Druid已经说明只需要配置数据库中的url地址就可以帮我们自动来匹配driverClassName,但是发现如果不配置这个,日志中总是有一些警告,所以就配置了一下。官网提供了一下他自己的driverClassName有:
[plain]
- jdbc:derby:=org.apache.derby.jdbc.EmbeddedDriver
- jdbc:mysql:=com.mysql.jdbc.Driver
- jdbc:log4jdbc:=net.sf.log4jdbc.DriverSpy
- jdbc:oracle:=oracle.jdbc.driver.OracleDriver
- jdbc:microsoft:=com.microsoft.jdbc.sqlserver.SQLServerDriver
- jdbc:jtds:=net.sourceforge.jtds.jdbc.Driver
- jdbc:postgresql:=org.postgresql.Driver
- jdbc:fake:=com.alibaba.druid.mock.MockDriver
- jdbc:hsqldb:=org.hsqldb.jdbcDriver
- jdbc:db2:=COM.ibm.db2.jdbc.app.DB2Driver
- jdbc:sqlite:=org.sqlite.JDBC
- jdbc:ingres:=com.ingres.jdbc.IngresDriver
- jdbc:h2:=org.h2.Driver
- jdbc:mckoi:=com.mckoi.JDBCDriver
接下来说一下web.xml中的配置参数都有什么,这里你也可以配置loginUserName和loginPassword,避免所有的人都可以看到你自己的数据库情况。这样子在你登录监控页面的时候就必须输入密码才可以访问了。当然也可以把你的IP加到allow之中,这样就只有你自己的机器可以访问这个监控界面了。例:
[html]
- <filter>
- <filter-name>DruidWebStatFilter</filter-name>
- <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
- <init-param>
- <!-- 经常需要排除一些不必要的url,比如.js,/jslib/等等。配置在init-param中 -->
- <param-name>exclusions</param-name>
- <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
- </init-param>
- <!-- 缺省sessionStatMaxCount是1000个。你可以按需要进行配置 -->
- <init-param>
- <param-name>sessionStatMaxCount</param-name>
- <param-value>1000</param-value>
- </init-param>
- <!-- druid 0.2.7版本开始支持profile,配置profileEnable能够监控单个url调用的sql列表 -->
- <init-param>
- <param-name>profileEnable</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>principalSessionName</param-name>
- <param-value>users.username</param-value>
- </init-param>
- <!-- 你可以关闭session统计功能
- <init-param>
- <param-name>sessionStatEnable</param-name>
- <param-value>true</param-value>
- </init-param> -->
- </filter>
- <servlet>
- <servlet-name>DruidStatView</servlet-name>
- <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
- <!--
- deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝。
- 如果allow没有配置或者为空,则允许所有访问
- -->
- <init-param>
- <param-name>allow</param-name>
- <param-value>128.242.127.1/24,127.0.0.1</param-value>
- </init-param>
- <init-param>
- <param-name>deny</param-name>
- <param-value>192.168.1.118</param-value>
- </init-param>
- <!-- 在StatViewSerlvet输出的html页面中,有一个功能是Reset All,执行这个操作之后,会导致所有计数器清零,重新计数 -->
- <span style="white-space:pre"> </span><init-param>
- <span style="white-space:pre"> </span><param-name>resetEnable</param-name>
- <span style="white-space:pre"> </span><param-value>false</param-value>
- <span style="white-space:pre"> </span></init-param>
- <span style="white-space:pre"> </span><!-- 用户名和密码 -->
- <span style="white-space:pre"> </span><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>
配置好web.xml之后,启动自己的JavaWeb服务,访问一下地址就可以看到Druid的监控界面。我在这里的访问地址是:http://192.168.1.118:8778/druid-monitor/druid/sql.html
输入用户名密码(druid/druid)就可以进入监控页面。
2.Druid Monitor监控JavaSE项目
监控javaSE项目可以通过jmx访问远程服务端,也可以通过到服务端运行官网提供的druidStat.sh命令。先说明一下怎么通过Jmx来访问,这一种既方便也不至于登录生产环境的服务器。
首先既然需要使用Jmx来访问,那么服务端就必须提供Jmx的访问端口和IP地址。那么需要在我们的启动文件中增加java的运行参数。需要添加-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname -Dcom.sun.management.jmxremote.port -Dcom.sun.management.jmxremote.authenticate -Dcom.sun.management.jmxremote.ssl参数来暴漏自己的服务器地址。例:linux的运行脚本
[plain]
- RESINWEBINF=/home/v31/common-biz
- LIBDIRS=${RESINWEBINF}/lib
- CP=.:${RESINWEBINF}/resources
- for Jars in `ls ${LIBDIRS}`
- do
- CP=${CP}:${LIBDIRS}/${Jars}
- done
- java -Xms2048m -Xmx2048m -cp ${CP} -Djava.net.preferIPv4Stack=true -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.1.76 -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false com.company.main.StartMain >>logs/error.log 2>&1 &
然后再部署一个web项目来访问这个JMX的IP和端口。启动服务,检查我们的端口是否已经启动
最后在我们本地的web.xml中配置jmxUrl地址来访问就可以查看到数据源的监控数据。例
[html]
- <servlet>
- <servlet-name>DruidStatView</servlet-name>
- <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
- <!-- 远程访问JavaSE项目使用jmx连接 -->
- <init-param>
- <param-name>jmxUrl</param-name>
- <param-value>service:jmx:rmi:///jndi/rmi://192.168.1.76:9004/jmxrmi</param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>DruidStatView</servlet-name>
- <url-pattern>/druid/*</url-pattern>
- </servlet-mapping>
配置好这些之后访问我们自己的web容器,发现果然可以查看统计信息了。还有人使用jconsole来访问,这个我没有尝试过,因为觉得那个操作对我来说太麻烦了。
3.Druid Monitor监控,使用druidStat.sh
这个命令脚本在git源码的druid\src\main\scripts目录下,
druidStat.bat脚本为:[plain]
- off
- rem Copyright 1999-2011 Alibaba Group Holding Ltd.
- rem
- rem Licensed under the Apache License, Version 2.0 (the "License");
- rem you may not use this file except in compliance with the License.
- rem You may obtain a copy of the License at
- rem
- rem http://www.apache.org/licenses/LICENSE-2.0
- rem
- rem Unless required by applicable law or agreed to in writing, software
- rem distributed under the License is distributed on an "AS IS" BASIS,
- rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- rem See the License for the specific language governing permissions and
- rem limitations under the License.
- set _RUNJAVA="%JAVA_HOME%\bin\java.exe"
- set _TOOLSJAR="%JAVA_HOME%\lib\tools.jar"
- %_RUNJAVA% -classpath "./druid-0.2.6.jar;%_TOOLSJAR%" com.alibaba.druid.support.console.DruidStat %*
druidStat.sh脚本为:
[plain]
- #!/bin/sh
- if [ -z "$JAVA_HOME" ] ; then
- echo "Error: JAVA_HOME is not defined."
- exit 1
- fi
- "$JAVA_HOME/bin/java" -Dfile.encoding="UTF-8" -cp "./druid-0.2.6.jar:$JAVA_HOME/lib/tools.jar" com.alibaba.druid.support.console.DruidStat $@
有了这个脚本,我们就可以直接在服务器上运行看到统计信息。这里我只说明一下linux的查看方式。我们修改一下druidStat.sh的druid-0.2.6.jar的目录和名称,然后放到自己的服务器上运行即可。先说明一下命令的使用方法吧。
看到了druidStat.sh的命令帮助,相信大家已经会了一多半了。接下来说明一下怎么使用。直接上图:
如果需要查看某一个ID的具体情况,可以使用-id -detail来查看sql的详情。
结尾:提供一个本项目的下载地址:
这个只是一个tomcat的运行项目包,而非源码包,所以直接复制到自己的tomcat中,然后修改其中的参数即可,不要导入到自己的eclipse中了。