【IT168 技术文档】本文主要研究如何利用 Linux Shell 脚本和飞信 API 来实现 MySQL 数据库的自动监控和短信报警,使 DBA 从繁重和重复的监控工作中解脱出来,一边享受马尔代夫的阳光、沙滩,一边实时监控北京的 MySQL数据库。
随着互联网及信息化的迅猛发展,企业运营所产生的数据量越来越大,所以大多数公司选择将重要商业数据存储在数据库中。如果数据库系统突然停机或发生其它故障,必然会影响公司的收入,声誉甚至导致用户投诉,如何保证数据库系统的正常运转,一直是公司关心的核心问题。这就要求 DBA 对数据库运行的各种状态进行实时监控,在发生故障之前解决它,将隐患消灭在摇篮中。本文给出使用 “MySQL Monitor” Shell 脚本来实现 MySQL 的实时监控,讨论了如何实现 MySQL的短信报警功能模块,同时结合一个真实应用场景来演示 “MySQL Monitor” 是如何工作的。
背景
南风公司遇到的问题
南风公司是一家互联网公司,该公司在北京网通1区机房有 10 台服务器,2 区机房有 10 台服务器,在上海电信 1 区机房也有 10 台服务器......,鉴于公司数据的重要性,DBA 必须实施一系列的监控措施来保证数据库良性运转,设置了包括操作系统磁盘空间检查、数据库表空间检查、数据库表状态检查、双机互备情况检查等 20 个检查点,DBA 有哪些选择去实施如此宠大的监控方案呢?下面是传统的解决方案:
这是一种低效的串行工作方式,DBA 必须每天从早上 10:00 开始逐台检查数据库服务器的 20个检查点,非常耗时,这种传统的方案会让 DBA 每天重复做机械化的工作,当有几百台被监控服务器时,这个传统的方案对 DBA 的来说就是噩梦,那么如何才能更有效的监控数据库成为 DBA 迫切需要解决的问题?
南风公司的解决方案
智慧的 MySQL,需要用智慧的方式去驾驭。南风公司的 DBA 开发了一套 “MySQL Monitor” 解决方案,这套方案充分利用了 “Shell 脚本” + “Linux Cron定时器服务” + “中国移动飞信免费发短信 API 接口” 的优势,只有在数据库检查点出现问题时才会向 DBA 发送短信进行报警,实现了真正意义上无人值守的大量数据库服务器监控框架,下面是全新的解决方案:
这是一种高效的并行工作方式,为了便于管理,我们先将数据库服务器进行了分组,每组服务器对应一个监控线程,并且这些监控线程部署在“监控工作站”上,大家 一定注意到“时间轴”消失了,这是因为这些监控线程是每 1 分钟运行一次,“时间轴”已经没有什么意义了。如果有一切正常,这些监控线程只会写日志,不会有其它的操作;如果当某台数据库服务器有异常情况发生,那么 “监控工作站”会给 DBA 终端发送短信提醒,这样 DBA 就可以在第一时间发现问题解决问题,即使 DBA 身边没有电脑终端也一样可以及时的了解 MySQL 服务器的运行情况。
核心技术
下面我们将简单介绍一下 “Shell” 、 “Cron” 、 “飞信API接口” 。
1、Shell 简介
Shell 是一种具备特殊功能的程序,它为我们和 Linux/Unix 系统之间提供了一个交互的接口。用户既可以输入命令来跟操作系统交互,也可以通过编写 Shell 脚本,从而完成更加自动化和复杂的操作。因此 Shell 被称作 Linux/Unix 系统的窗口,它的作用就是按照一定的语法规范将用户指令加以转化并传给系统进行处理。
跟 DOS 可以分为 MS-DOS,PC-DOS,FreeDOS,ROM-DOS 一样,每种 Linux/Unix 操作系统都有它们自已的 Shell。它可以简单的理解为一个应用程序,可以在独立于操作系统本身的情况下进行修改、更新或是增删功能。Linux/Unix 操作系统提供了几种不同的 Shell, 如 Bourne Shell(/bin/sh)、Korn Shell(/bin/ksh)、Bourne Again Shell(/bin/bash)、Tenex C Shell(tcsh)、C Shell(/bin/csh) 等,其中 Bourne Again Shell(即bash) 是自由软件基金会(GNU)支持开发的一个 Shell 版本,它是 Linux 系统中一个默认的 Shell,Bash 不但与其它几种 Shell 兼容,而且还继承发扬了它们的优点。
让我们看一个 Shell 代码示例,我们将这个文件命令为 create_folder_daily.sh :
清单 1. Shell 代码示例
current_date=`date +%Y%m%d`
mkdir $current_date
这段代码的功能是:在当前目录下创建一下以当前日期(如:20091016)为命名的目录,运行演示如下:
清单 2. Shell 代码运行演示
总计 4
-rwxrwxrwx 1 root root 61 10-17 07:32 create_folder_daily.sh
[root@localhost workdir]# ./create_folder_daily.sh
[root@localhost workdir]# ll
总计 8
drwxr-xr-x 2 root root 4096 10-17 07:46 20091017
-rwxrwxrwx 1 root root 61 10-17 07:32 create_folder_daily.sh
2、Linux Cron 定时器服务
Linux Cron 是一个常驻服务,它提供定时器的功能,让用户在特定的时间得以执行预设的指令或程序。只要用户会编辑计时器的配置文件,就可以使用定时器的功能。
cron 的配置格式如下:Minute Hour Day Month DayOFWeek [UserName] Command
字段名 描述 |
Minute 分钟,表示每个小时的第几分钟来执行。范围是从 0-59 |
Hour 小时,表示从第几个小时来执行,范围是从 0-23 |
Day 日期,表示从每个月的第几天执行,范围从 1-31 |
Month 月,表示每年的第几个月来执行,范围从 1-12 |
DayOFWeek 周,表示每周的第几天执行,范围从 0-6,其中 0 表示星期日 |
UserName 用户名,也就是执行程序要通过哪个用户来执行,这个一般可以省略 |
Command 要执行的命令(命令可以是 ls /proc >> /tmp/proc 之类的命令,也可以是执行你自行编写的脚本的命令) |
配置 cron 任务的语法:crontab [option] [username]
语法 | 描述 |
crontab -e [username] | 编辑该用户的计时器设置 |
crontab -l [username] | 列出该用户的计时器设置 |
crontab -r [username] | 删除该用户的计时器设置 |
crontab -v [username] | 列出该用户cron作业的状态 |
清单 3. Crontab 配置演示 上面的配置将使 create_folder_daily.sh 每天凌晨 1 点钟运行一次,也就是说每天都会在 /root/workdir/ 目录下生成一个以当前日期命名的文件夹。
0 1 * * * /root/workdir/create_folder_daily.sh
3、中国移动飞信免费发短信 API 接口
飞信是由中国移动通信集团公司推出的一款集商务应用和娱乐功能为一体的,基于手机应用以及与 Internet 深度互通的即时通讯产品,可免费给好友发送短信。下载中国移动飞信 PC 客户端软件,并注册开通飞信。注册成为飞信用户,下载飞信PC客户端、使用 PC 客户端基本功能,不收取费用。通过 API 接口,即可免费给飞信好友或给你自己的手机发短信。利用本 API 接口可进行日程提醒、服务器监控、报警、故障通知或短信自动控制等功能。
它有 2 种调用方式:
清单 4. 浏览器调用方式
https://fetionlib.appspot.com/restlet/fetion/您手机号/您的飞信密码/接收方手机号/短信内容
清单 5. Linux下调用方式
curl "https://fetionlib.appspot.com/restlet/fetion/您手机号/您的飞信密码/接收方手机号/短信内容"
流程设计
程序主要分为 monitor.sh 主监控程序和 monitor_helper.sh 助手程序,下面将分别介绍:
1、monitor.sh
主监控程序,每 1 分钟运行一次,如果发现了某个检查点有问题,程序会自动给 DBA 发送一条短信,这样做是为了保证在出现问题的时侯 DBA 能在最短的时间内做出反映。
主监控程序流程图,如下:
正如上面展示的,只有某个检查点出现问题的时候,才会给DBA发短信提醒,如果正常的时候只会写日志,不会打扰DBA,这样保证让DBA更专心的做其它工作。
2、monitor_helper.sh
那么大家想一下,如果主监控进程停掉了怎么办呢?我们会误认为一切监控检查点都是正常的,所以我们需要一个方案来保证主监控程序正常运转,于是助手程序产生,每天 10 点运行一次,用于辅助主监控程序。它有如下 2 个功能:
监控主程序是否正常运转:它每天扫描日志文件,如果主监控程序当天的日志文件存在,那么说主监控进程是正常工作的,此时助手程序不做什么动作;如果找不到日志,那么它会给 DBA 发短信提醒主监控进程意外死掉了。
清理日志:由于主监控程序是每分钟调用 1 次,那么随着时间的推移它会产生大量的日志文件,如果不清理,会直接影响机器的存储空间,所以需要此助手程序进行日志清理的
助手程序流程图,如下:
这样我们即有主监控程序,又有助手程序,所以程序的安全性已经很高了,这回DBA就可以高枕无忧了。
项目实战
我们依然以南风公司为例,但需要将真实的情况缩小为一个便于大家理解的模型,所以我们假设该公司分别在北京和上海各有 1 组服务器(真实情况有更多组服务器),北京网通 1 区机房这组服务器里有 2 台服务器(真实情况是每组有更多的服务器),上海电信 1 区机房也有 2 台服务器(真实情况是每组有更多的服务器)。
程序目录结构及说明如下:
1、.profile文件说明
配置文件,存储常量信息、短信收发方相关信息及数据库服务器配置信息等,具体如下:
清单 6. .profile 文件
LOG_DIR=log
SENDER_ID=137********
SENDER_PWD=pwd********
RECEIVER_LIST=Tom~137********
SERVER_GROUP_CFG_DIR=server_group_cfg
EXPIRED_DAY=2
变量名 | 变量描述 |
LOG_DIR | 表示 monitor.sh 产生的日志文件的路径 |
SENDER_ID | 短信发送方手机号 |
SENDER_PWD | 短信发送方飞信密码 |
RECEIVER_LIST | 短信接收方列表 |
SERVER_GROUP_CFG_DIR | 服务器组配置文件的路径 |
EXPIRED_DAY | 用于 monitor_helper.sh 清理日志时用,此处为 2 表示清除 2 天前的日志 |
2、bj_cnc1 文件说明
服务器组配置文件,存储每组服务器中所有数据库的配置信息,具体如下:
清单 7. bj_cnc1 文件
第100号MySQL:86.160.1.100:1521:test_user0:test_pwd0:test_db_100
第101号MySQL:86.160.1.101:1522:test_user1:test_pwd1:test_db_101
表示北京网通1区中所有数据库的配置信息,本例仅以 2 个库为例,每个字段的含义如下:
列号 | 描述 |
第1列 | 数据库的中文描述 |
第2列 | 数据库的 IP 地址 |
第3列 | 数据库的监听端口 |
第4列 | 数据库用户名 |
第5列 | 数据库用户密码 |
第6列 | 服务器的名字 |
3、bj_cnc1_20091017 文件说明
这个是日志文件,表示 2009 年 10 月 17 日北京网通1区 monitor.sh 主监控程序产生的日志。
4、monitor.sh 文件说明
主监控程序,每 1 分钟运行一次,它接受一个输入参数,用于指定监控哪个服务器组(如 monitor.sh -s bj_cnc1,表示监控“北京网通1区”下的 2 个数据库“第100号MySQL”和“第101号MySQL”),并将日志写入 log 目录下,并且 log 命名为“bj_cnc1_20091017”,表示是“北京网通1区”服务器组在 2009 年 10 月 17 日产生的日志。
程序框架,如下:
# 此处是一些初始化的工作
function echo_usage(){
# 打印程序的用法
}
function send_msg(){
# 发送短消息
}
function check_mysql_instance_status(){
# 检查点 1, 用于检查此数据库监听器是否启动,同时写日志
# 如果失败则调用“send_msg()”给 DBA 发短信提醒
}
# 可以自定义多个检查点
function check_***(){
# 检查点 n,同时写日志
# 如果失败则调用“send_msg()”给 DBA 发短信提醒
}
function main(){
# 主函数
check_mysql_instance_status
# 可以调用多个检查点
check_***
}
# 此处检查输入的参数是否合理,如果不合理则调用“echo_usage”,并退出程序
# 主函数调用
main
5、monitor_helper.sh 文件说明
由于主监控程序每 1 分钟运行一个,那么如果主监控程序在 2009 年 10 月 17 日是运行的,那么它将在 log 目录下会产生一个 bj_cnc1_20091017,正是这个文件可以代表主监控程序是运行良好的。
助手程序循环读取“server_group_cfg”文件夹下面的文件名(如“bj_cnc1”),然后在文件名后加上当前日期(如 “bj_cnc1_20091017”),再到 log 目录下去找该文件,如果找到则说明正常,如果找不到就说明有主监控程序没有正常运行。
程序框架如下:
清单 9. monitor_helper.sh 文件
# 此处是一些初始化的工作
function send_msg(){
# 发送短消息
}
function check_monitor(){
# 检查主监控程序是否运行,如果失败则调用“send_msg()”给 DBA 发短信提醒
}
function del_expired_log(){
# 删除主监控程序产生的过期日志
}
function main(){
# 主函数
}
# 主函数调用
main
6、Cron 定时器配置文件说明
我们将主程序和助手程序放到定时器里,他们的运行频率分别是:主监控程序, 每 1 分钟运行一次;助手程序,每天 10 点运行一次;具体代码如下:
清单 10. Cron 定时器配置文件
*/1 * * * * /home/mysql1/MySQL_Monitor/monitor.sh -s sh_ct1
0 10 * * * /home/mysql1/MySQL_Monitor/monitor_helper.sh
7、程序运行演示
如果“北京网通1区”的“第100号MySQL”所属实例意外停止了,那么 DBA 会马上收到这样一条短信,如下:
结论
本文对传统的 MySQL 监控工作方式进行了优化和升级,使其搭上了移动互联的快车,让 DBA 可以更高效的工作。我们需要做的还很多,伴随互联网和移动互联的兴起,将会有更多的技术可以让 MySQL 更加智能,更加方便为用户服务。