前言
其实这篇博客并没有什么技术含量,主要是想做个记录:解决问题的方法有多种,不要着急动手,要多思考,或许会有更好更快的解决方法。
多思考,找更好的解决方法
工作中,对接第三方接口是常见的事情。接口响应异常也是很常见的事情。当出现一些意料之外的异常,则需要拿出相关日志提供给对接方,待对接方处理。而如果每次出现异常都需要开发人员去登录服务器再去搜索相关日志再提供给对接方,那么这个过程是比较慢的。首先如果开发人员不在,那么没人可以处理。其次,即使开发人员在,也不一定能即使响应。于是,倒不如在后台系统中增加一个模块,提供给工作人员查找接口异常信息。这样当系统出现异常,工作人员也能快速拿到异常信息,就能马上提供给对接方排查问题。
接口的异常信息,自然是记录到数据库里。可是这种异常信息没必要一直保留,即我们可以选择保留最近一个月的。那么问题就来了,如何实现这个过期清除呢?
第一个想法是:在程序里增加一个定时器,每天执行一次,清除距离当前时间超过一个月的记录。
可是却觉得这种做法很笨重。这样做的话,如果突然要改成保留最近两个月,那么我就要改代码,并且要重新部署。重新部署就会影响线上程序的使用。
第二个想法是:新建一个模块,这个模块就只有一个定时器,也是每天执行一次,清除距离当前时间超过一个月的记录。
可是依然觉得笨重。为单独的一个功能新建一个模块,感觉有点浪费服务器资源了。
第三个想法是:或许数据库本身就能提供这样的功能呢?
毕竟我的操作并不依赖于外部数据。于是了解了一番,果然MySQL是支持的:通过定义存储过程和定时事件,在定时事件中执行存储过程。这样就能轻便的实现这个功能了,而且能快速的修改而不影响线上程序。
对比想到的就是这三种方法,显然第三种更好,于是就是动手实践了。其实我没能直接想到第三种方法,也说明了我对数据库的存储过程和定时事件不了解,确实如此。那就顺便学习一番吧。
MySQL实现定时任务
相关操作参考的是这篇博客:https://blog.csdn.net/kzdwts/article/details/79282154,这里我也整理下,做个笔记。
首先查看定时器运行状态:
SHOW VARIABLES LIKE 'event_scheduler';
如果定时器没有打开,则打开定时器:
SET GLOBAL event_scheduler='ON';
然后创建存储过程,在存储过程中就可以写我们的删除数据的sql:
create PROCEDURE procedureToCleanData()
BEGIN
delete from tb_req_resp_info where DATEDIFF(now(),created) > 30;
END;
接着,创建定时任务,定义每天执行一次,默认创建时是开启状态:
create event if not exists eventJob
on SCHEDULE every 1 day
on COMPLETION PRESERVE
do call procedureToCleanData()
我们也可以手动操作,开启定时任务,即设置状态为ENABLE
:
ALTER EVENT 事件名称_event ON COMPLETION PRESERVE ENABLE;
以及关闭定时任务,设置状态为DISABLE
:
ALTER EVENT 事件名称_event ON COMPLETION PRESERVE DISABLE;
以及查看所有的的event
SELECT * FROM mysql.`event`;