一、SQL-Monitor引入背景
如今大部分的Java项目都是使用Mybatis作为数据库持久层。在使用Mybatis时,我们会在Mapper XML文件编写的SQL语句,但是这些SQL语句都是带有参数判断、条件判断等。在没有给定参数的情况下,可能无法推断出完整的SQL语句。又或者给定一个完整的SQL语句,也很难定位是由哪个Mapper的哪个方法触发的。因为类似的SQL语句可能在一个Mapper的多个方法中,或者在多个Mapper文件中。
使用阿里云的RDS数据库服务,当SQL语句的执行影响了数据库性能时,会收到告警信息。但是数据库监控中会显示完整的SQL语句,从而很难根据完整的SQL语句推断出是由哪个Mapper的哪个方法造成的。无法及时对Mapper文件中的SQL语句进行优化。
SQL-Monitor工具利用Mybatis的插件Interceptor能力。可以监控:完整的SQL语句、程序的调用栈、Mapper路径、SQL语句的耗时等信息,从而根据完整的SQL语句快速定位是哪个Mapper的哪个方法触发的。同时也提供了慢SQL的钉钉通知功能,当SQL语句的执行时间大于设置的阈值时,使用钉钉及时通知用户出现了一个慢SQL,从而及时对慢SQL进行优化。
SQL-Monitor具体代码参考github:https://github.com/1997chang/sqlmonitor
二、SQL-Monitor功能
SQL-Monitor工具为用户提供如下功能:
2.1. 记录SQL语句内容
记录每一个由Mybatis操作数据库的CRUD内容。其中信息主要包含:
①完整的SQL语句(参数已经填入,可以直接在数据库中执行)
②Mapper文件和方法
③CRUD操作的JAVA调用栈信息
④SQL语句执行耗时等信息。
然后使用指定的存储策略对监控到的SQL记录进行持久化存储。
其中SQL-Monitor自带存储策略包含两种:默认为LOGGER。
Logger打印
ES存储
也可以自己实现存储策略,只要实现com.moxiao.sqlmonitor.store.StorePolicy类
例如:使用LOGGER日志记录操作内容。当DEBUG模式开启,将会额外打印JAVA调用栈的信息
SQL-Monitor检测到执行的SQL语句,StatementId:【com.example.mybatis.log.Count.count】SQL语句为:【select count(*)
from names】,开始执行时间:【2023-03-15 11:35:05】,耗时:【4】ms
2.2. 通知慢SQL语句
当一条SQL语句的执行时间大于executeTimeLimit,则该SQL语句会被定义为慢SQL语句。使用指定的通知策略对慢SQL进行通知。及时告知用户出现慢SQL语句。
通知类型有两种:
当SQL语句执行完进行的通知。当SQL语句执行完,并且执行时间大于executeTimeLimit,使用指定的通知策略进行通知。
其中通知信息:
① Mapper路径
② 完整的SQL语句
③ 执行SQL语句总耗时
④ 执行SQL语句的栈内容
这里设置的慢SQL的阈值为1ms
定时监控任务进行的通知。如果SQL语句还没有执行完成,但该SQL语句已经执行时间大于executeTimeLimit,由定时监控任务进行通知。注意:定时监控的时间间隔为slowSqlMonitor。单位ms
其中通知信息:
① 已经执行了时间,但SQL语句还没有执行完成
② Mapper路径
③ 完整的SQL语句
④ 开始执行SQL语句时间
⑤ 执行SQL语句的栈内容
其中SQL-Monitor自带的通知策略为:钉钉通知,默认为DINGDING。也可以自己实现存储策略,只要实现com.moxiao.sqlmonitor.notice.NoticePolicy类
三、SQL-Monitor的使用
3.1. 添加依赖
<dependency>
<groupId>io.github.1997chang</groupId>
<artifactId>sqlmonitor-mybatis</artifactId>
<version>最新版本</version>
</dependency>
注意:当使用钉钉进行通知的时候:除了配置钉钉机器人的配置信息以外,还要添加okhttp3依赖,版本要求4.1.0以上
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
3.2. 设置Mybatis插件
在MyBatis配置文件中配置拦截器插件
<plugins>
<plugin interceptor="com.moxiao.sqlmonitor.interceptor.SqlMonitorInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<property name="param1" value="value1"/>
<!-- 例如:SQL5秒表示慢SQL,钉钉通知地址,ES配置文件的地址,存储策略
<property name="executeTimeLimit" value="5000"/>
<property name="slowSqlMonitor" value="5000"/>
<property name="dingdingConfig.secret" value="SECd115fa66c6782b3e6bd361a73ee9a66bd53bb3697466cbb6457c27e335799f1a"/>
<property name="dingdingConfig.accessToken" value="10f12cead3ce688dc030a35ad584f90aed07af401bd918b652c99a2180e77f2b"/>
<property name="esConfig.uri" value="https://localhost:9201,https://localhost:9202,https://localhost:9203"/>
<property name="esConfig.username" value="elastic"/>
<property name="esConfig.password" value="elastic"/>
<property name="esConfig.fingerPrint" value="11be02bc53f0b5f0cb5aae184411f76b916437508c7938f1963a2b00e63ea9e5"/>
<property name="storePolicy" value="LOGGER,ES"/>-->
</plugin>
</plugins>
在Spring Bean的XML配置文件配置拦截器
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="plugins">
<array>
<bean class="com.moxiao.sqlmonitor.interceptor.SqlMonitorInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个 -->
<value>
params=value1
</value>
</property>
</bean>
</array>
</property>
</bean>
具体参数说明参考github仓库:https://github.com/1997chang/sqlmonitor
更多精彩内容:请关注公众号: