数据库又慢了?你需要一个像样的慢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报警系统,本质上是在构建一个"数据库性能风险的早期预警系统"。它要求我们不仅是技术的堆砌,更是对数据库性能管理的深刻理解。

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

相关推荐
guodingdingh2 小时前
软件开发工作问题总结0718
java·开发语言·数据库
咖啡八杯4 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
优橙教育4 小时前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
掘金码甲哥4 小时前
这块终端神器, 必须吹爆!
后端
糖果店的幽灵4 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
Csvn5 小时前
📊 SQL 入门 Day 8:集合操作 — 用 SQL 做数学里的"并交差"
后端·sql
腻害兔6 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
SeaTunnel6 小时前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
碎光拾影6 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
Miao121317 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言