SpringBoot:SpringBoot集成Druid监控慢SQL

一、前言

**  数据库连接池是一个至关重要的组成部分,一个优秀的数据库连接池可以显著提高应用程序的性能和可伸缩性。常见的连接池:Druid、HikariCP、C3P0、DBCP等等,不过目前大部分都是使用Druid或者SpringBoot默认的HikariCP!**

**  本文将详细介绍如何在Spring Boot项目中配置数据源,集成Druid连接池,以实现更高效的数据库连接管理。**

二、常见的连接池介绍

1. C3P0

**  开源的JDBC连接池**:C3P0实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。

**  稳定性好**:尽管速度相对较慢(只是慢一丢丢),但稳定性很好,Hibernate和Spring底层就使用了C3P0。

2. DBCP

**  Tomcat的数据库连接池**:Apache Tomcat DBCP是一个用于管理数据库连接的组件,通常与Apache Tomcat服务器一起使用。

**  高效管理**:它提供了一种机制来有效地管理数据库连接,以便在高负载下提供更好的性能和可伸缩性。

**  配置灵活**:可以通过Tomcat的配置文件(如context.xml)或者直接在应用程序中的代码中配置连接池的各种参数。

**  验证和性能优化**:DBCP可以配置为在从连接池中获取连接时验证连接的有效性,并避免在每次数据库请求时都重新创建和销毁连接,从而提高了性能和效率。

3. HikariCP

**  高性能**:HikariCP是一个高性能的Java数据库连接池,它通过使用异步和非阻塞的方式,以及一些性能优化的技术,实现了卓越的连接获取和释放性能。

**  轻量级**:HikariCP的代码库非常小,只有几百KB大小,不依赖大量的外部库和复杂的依赖关系。

**  自动化管理**:HikariCP具有自动化管理连接池的功能,可以根据应用程序的需求动态调整连接数,并自动管理连接的生命周期。

**  配置灵活**:提供丰富的可配置选项,支持连接池的最大连接数、最小空闲连接数、连接超时时间等多种配置参数。

4. Druid

**  高性能**:Druid使用多线程和缓存技术,能够充分发挥数据库的性能,提高应用程序的响应速度。

**  监控功能**:Druid提供了丰富的监控功能,可以帮助开发人员及时发现和解决数据库连接池的问题。

**  扩展性强**:Druid具有良好的扩展性,可以轻松地与其他框架集成,满足不同应用程序的需求。

**  防御能力**:Druid具有强大的防御机制,可以有效地防止SQL注入等攻击。

三、Druid介绍

Druid是一个由阿里巴巴开源的数据库连接池实现,它结合了C3P0、DBCP等数据库连接池的优点,并加入了日志监控功能。Druid支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等,并针对Oracle和MySql做了特别优化。

Druid不仅是一个数据库连接池,还提供了强大的监控功能,可以监控SQL的执行时间、ResultSet持有时间、返回行数、更新行数等关键指标,有助于线上分析数据库访问性能

四、Druid的优缺点

Druid的优点:

**  高性能**:Druid能够在高并发的环境下提供稳定、快速的数据库访问服务。它使用内存缓存、线程池、连接池等先进技术来实现高性能,并且支持对SQL进行解析和优化,选择最合适的执行计划,从而提高数据库的执行效率。

**  可扩展性**:Druid具有很好的可扩展性,能够根据业务的发展进行灵活的扩展。其设计采用了模块化的思想,各个模块之间解耦,方便进行扩展和升级。同时,Druid还支持各种数据库,可以在不同的数据库之间进行切换。

**  稳定性**:Druid具有很高的稳定性,能够在系统运行过程中保持稳定,不会出现大的波动。它在内部实现了自动均衡和负载均衡的功能,能够根据数据库服务器的负载情况自动调整负载,保持了系统的稳定性。此外,Druid还具有完善的异常处理机制,能够及时处理异常情况,避免对系统造成大的影响。

**  强大的监控能力**:Druid具有强大的监控能力,能够实时监控和统计系统的各项指标,如连接数、SQL执行效率、系统负载等。此外,它还支持与第三方监控系统进行集成,方便进行系统的监控和管理。

**  丰富的功能**:Druid具有丰富的功能,如支持对SQL语句进行动态配置、数据库备份和恢复、分库分表等功能,方便对数据进行管理和访问。

**  高可用性**:Druid连接池支持对连接的有效性进行检测,可以自动剔除无效的连接,并重新创建新的连接来保证连接的可用性。这些检测机制可以避免应用程序使用无效的数据库连接,提高了应用程序的稳定性和可靠性。

**  安全性**:Druid连接池提供了多种安全特性,包括防止恶意代码注入、SQL注入和XSS攻击等。它还支持按照IP地址、用户名和密码等方式对连接进行白名单和黑名单过滤,增强了数据库连接的安全性。

**  配置灵活**:Druid连接池具有丰富的配置选项,可以灵活地配置连接池的参数,以满足不同应用程序的需求。

Druid的缺点:

**  依赖性**:将Druid引入项目会增加项目的依赖,可能会影响构建和部署的复杂性。

五、Springboot集成Druid

1. 添加依赖

java 复制代码
<!-- druid数据源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.23</version>
</dependency>

<!-- mysql驱动-->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.30</version>
</dependency>


<!--mybatis,引入了 SpringBoot的 JDBC 模块,所以,默认是使用 hikari 作为数据源-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.0</version>
    <exclusions>
        <!-- 排除默认的 HikariCP 数据源 -->
        <exclusion>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2. 添加配置

java 复制代码
# 数据库连接配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mysql?relaxAutoCommit=true&zeroDateTimeBehavior=convertToNull&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

# 配置初始化大小、最小、最大
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=10

# 配置获取连接等待超时的时间(单位:毫秒)
spring.datasource.druid.max-wait=60000

# 配置StatViewServlet(监控页面),用于展示Druid的统计信息
spring.datasource.druid.stat-view-servlet.enabled=true

# 访问内置监控页面的路径,内置监控页面的首页是/druid/index.html
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
powershell 复制代码
# 监控页面账户与密码
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin

# 配置WebStatFilter,用于采集web关联监控的数据
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*

# 开启druiddatasource的状态监控
spring.datasource.druid.filter.stat.enabled=true
spring.datasource.druid.filter.stat.db-type=mysql

# 开启慢sql监控
spring.datasource.druid.filter.stat.log-slow-sql=true

# 超过500ms 就认为是慢sql,记录到日志中,为了测试我这边设置的小一点
spring.datasource.druid.filter.stat.slow-sql-millis=2

# 也可以这样子,不过这个使用的都是默认配置了
spring.datasource.druid.filters=stat,wall

3. 启动项目后,访问 /druid/index.html,输入上面配置中的用户名与密码

4. 去除广告

进来之后发现这里有个广告。展示的不太友好啊。

添加一个过滤器,把这里不需要显示的js给过滤掉。

java 复制代码
@Configuration
@ConditionalOnWebApplication
@AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true", matchIfMissing = true)
public class DruidAdConfig {

    @Bean
    public FilterRegistrationBean removeDruidAdFilterRegistrationBean(DruidStatProperties properties) {

        // 获取web监控页面的参数
        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
        // 提取common.js的配置路径
        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");

        final String filePath = "support/http/resources/js/common.js";

        //创建filter进行过滤
        Filter filter = new Filter() {
            @Override
            public void init(FilterConfig filterConfig) throws ServletException {}

            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                chain.doFilter(request, response);
                // 重置缓冲区,响应头不会被重置
                response.resetBuffer();
                // 获取common.js
                String text = Utils.readFromResource(filePath);
                // 正则替换banner, 除去底部的广告信息
                text = text.replaceAll("<a.*?banner\"></a><br/>", "");
                text = text.replaceAll("powered.*?shrek.wang</a>", "");
                response.getWriter().write(text);
            }

            @Override
            public void destroy() {}
        };

        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
}

重新启动项目,重新登陆账号进入查看。

5. SQL监控页面

执行一些接口调用之后,在查看SQL监控页面。

提供了慢SQL的统计信息,如慢SQL的数量、总执行时间、执行行数等。

六、获取Druid的监控数据

**  Druid的监控数据可以在开启StatFilter后 ,通过DruidStatManagerFacade进行获取。DruidStatManagerFacade#getDataSourceStatDataList该方法可以获取所有数据源的监控数据,除此之外 DruidStatManagerFacade 还提供了一些其他方法,可以按需选择使用。**

java 复制代码
@RestController
@RequestMapping(value = "/druid")
public class DruidStatController {

    @GetMapping("/stat")
    public Object druidStat(){
        // 获取数据源的监控数据
        return DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
    }
}

**  Druid是一个功能强大、性能优异、易于使用、可扩展和可靠的数据库连接池。在实际应用中,它已经被广泛应用于各种高并发、大数据量和大批量请求的业务场景中,并得到了业界的广泛认可和好评。使用它可以帮我们创建和管理数据库连接,可以使用慢sql等监控功能,使用数据库密码加密等丰富的扩展功能。**

相关推荐
wyiyiyi23 分钟前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
一只爱撸猫的程序猿1 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋1 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
阿华的代码王国1 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy2 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack2 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9653 小时前
pip install 已经不再安全
后端
寻月隐君3 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github
武昌库里写JAVA3 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
Java小白程序员4 小时前
Spring Framework:Java 开发的基石与 Spring 生态的起点
java·数据库·spring