数据库又慢了?你需要一个像样的慢SQL报警系统

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

在当今数据驱动的时代,数据库是任何应用系统的核心。而慢SQL,则是数据库最怕又最常见的问题。它悄然滋生,初期难以察觉,但一旦爆发,便会导致应用响应迟缓、系统资源耗尽,甚至引发服务雪崩。

因此,一个设计良好的慢SQL报警系统,不再是可选项,而是保障系统稳定性和用户体验的生命线。

02 契机

前两天帮同事排查一个问题,线下都是好好的,一到生产环境,代码卡死,最后通过Arthas工具才发现,是因为慢SQL导致的,耗时大概1分钟左右。真的是吃了大亏了。

但是,当时的大坑就是因为慢SQL导致客户端超时超时,拿到的数据结果为空,从而报空指针异常,被空指针直接误导带偏。

Arthas虽然可以采集结果,但也只是全部执行完成之后才会打印信息。慢SQL会直接将信息阻塞,给人的错觉就是没有执行到监控的地方。

于是想,如果SQL执行完执行时间超过某个阈值,自动推送消息,就可以快速定位到问题了。带着这个问题,我们开启今天的文章介绍。

03 Mysql自带的参数

Mysql本身支持慢SQL的监控,会将超过阈值的SQL保存到执行的位置。关键参数如下:

  • slow_query_log:开启慢SQL日志的开关(ON/OFF)
  • slow_query_log_file:慢SQL存放的位置
  • long_query_time:阈值,单位秒(s)

3.1 设置命令

这些参数可以在Mysql的配置文件里面修改,也可以通过命令修改。我们先通过命令查看:

sh 复制代码
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';
SHOW VARIABLES LIKE 'long_query_time';

3.2 监控文件

我们通过SHOW VARIABLES LIKE 'slow_query_log_file'找到慢SQL的位置,通过命令可以追踪日志:

sh 复制代码
tail -f /data/log/slow.log

当有慢SQL超过阈值会自动将信息写入文件。

3.3 日志采集

文件监控到了,但是并不能主动报警,我们需要采集日志数据然后分析报警。日志的采集工具有很多如:FilebeatLogStashFloume等。

关于日志采集我们会后期会专门用一期讲,这里就不在赘述!

04 Mybaits拦截器监控

Mybaits拦截器不仅能够打印SQL,当然还可以监听SQL执行的时间。这个需要我们自己去实现,灵活度更好,不需要任何第三方的插件。

4.1 拦截器案例

java 复制代码
@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class})
})
@Component
public class SqlExcuteTimeInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StopWatch watch = new StopWatch("SqlExcuteTimeInterceptor");
        watch.start();
        Object proceed = invocation.proceed();
        watch.stop();

        // 打印SQL
        StatementHandler handler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = handler.getBoundSql();
        // 获取原始SQL
        String sql = boundSql.getSql();
        Object param = boundSql.getParameterObject();

        // 美化SQL输出
        System.out.println("\n=============== SQL日志 ===============");
        System.out.println("原始SQL:" + sql);
        System.out.println("SQL: " + sql.replaceAll("\\s+", " ").trim());
        System.out.println("参数: " + JSON.toJSONString(param));
        System.out.println("执行SQL耗时: " + watch.getTotalTimeMillis() + "ms");
        System.out.println("=========================================");
        return proceed;
    }
}

我们的拦截器中进行了执行时间的计算以及SQL的打印。要注意的是,我们的拦截器针对queryupdate方法进行了拦截。

4.2 实现效果

这里的效果只是将结果打印出来。实际应用中,需要根据执行的时间和配置阈值校验,最后推送给负责人。可以通过企业微信、钉钉、微信、手机短信等工具。

05 小结

其实很多三方工具(如SkyWalking等)已经集成了SQL的报警,尤其云厂商。只需要配置对应的报警方式即可。但是针对一些小微企业,类似拦截器这样的实现更能满足个性的话需求,最重要的节省成本。

而我们要做的就是设计好慢SQL的报警,要设计一个慢SQL报警系统,本质上是在构建一个"数据库性能风险的早期预警系统"。它要求我们不仅是技术的堆砌,更是对数据库性能管理的深刻理解。

从一个简单的日志收集器,到一个具备智能分析、精准报警和闭环治理能力的平台,每一步进化都将为业务的稳定和高效运行注入更强的韧性。投资这样一个系统,就是投资系统的未来。

相关推荐
短剑重铸之日5 小时前
《ShardingSphere解读》07 读写分离:如何集成分库分表+数据库主从架构?
java·数据库·后端·架构·shardingsphere·分库分表
知我Deja_Vu5 小时前
【避坑指南】ConcurrentHashMap 并发计数优化实战
java·开发语言·python
wefly20176 小时前
m3u8live.cn 在线M3U8播放器,免安装高效验流排错
前端·后端·python·音视频·前端开发工具
daidaidaiyu6 小时前
Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML)
java·spring
zhanggongzichu7 小时前
小白怎么理解后端分层概念
后端·全栈
鬼蛟7 小时前
Spring————事务
android·java·spring
西门吹-禅8 小时前
【sap fiori cds up error】
java·服务器·sap cap cds
stark张宇8 小时前
Golang后端面试复盘:从Swoole到IM架构,如何支撑360w用户的实时消息推送?
后端
小码哥_常8 小时前
从0到1:搭建Spring Boot 3企业级认证授权平台
后端
敲代码的嘎仔8 小时前
Java后端面试——SSM框架面试题
java·面试·职场和发展·mybatis·ssm·springboot·八股