共计 2233 个字符,预计需要花费 6 分钟才能阅读完成。
背景
某业务人员反应系统登陆不上去,于是程序员自己试着登陆系统成功了,心里很自信的认为“我的代码没有问题”,便让业务人员再试试。然后业务人员是登陆成功了,但是整个系统用起来很卡,这下程序员意识到是系统的问题了。
排查步骤
因为刚刚上线了新的功能,想到了配置了定时任务,可能是定时任务配置错误,导致 PHP 启了过多进程。
使用命令ps -ef | grep php
查看,果然是起了很多没必要的更新数据脚本,其中涉及到与第三方接口的交互并且有大量的更新数据库的操作,所以直接导致系统卡顿。
使用命令 crontab -l
查看 crontab 配置,有几个脚本的执行频率是想配置成每小时执行一次,结果配置错误,导致每分钟执行一次。具体如下:
# 错误配置
* */1 * * * /usr/local/bin/php /data/site/demo/yii demo/sync-product
# 正确配置
0 */1 * * * /usr/local/bin/php /data/site/demo/yii demo/sync-product
问题是排查到了,现在需要做的就是快速 kill 掉那些没必要的进程。这时候便想到了万能的 awk 命令,如下:
ps -ef | grep php | awk '{print $2}' | xargs kill -9
执行后,系统开始恢复稳定。
思考
整个问题排查总结下来,归根结底还是配置 crontab 是不够细心。
同时也引发了其他的一些思考, 总结后整理如下:
系统突然出现卡顿,常用的排查思路有哪些呢?
- 查看内存使用状况:
free -g
- 查看磁盘使用状况:
df -h
- 查看磁盘 I / O 使用:
iostat -dx
- 查看 CPU 使用:
top
具体的系统调优,本文不做介绍了。
awk 命令的基本使用
常用命令
awk '条件类型 1{动作 1} 条件类型 2{动作 2} ...' filename
awk 后面接两个引号并加上大括号来设置想要对数据进行的处理动作。
例如:我们要取出账号与登录者的 IP, 且之间以 [TAB] 隔开,则:
[release@api_02 ~]$ last -n 5 | awk '{print $1"\t"$3}'
release 117.111.111.11
release 117.111.111.11
release 117.111.111.11
release 117.111.111.11
release 117.111.111.11
awk 还存在一些内置变量
变量名称 | 代表意义 |
---|---|
NF | 每一行拥有的字段总数 |
NR | 目前 awk 处理的是第几行 |
FS | 目前的分隔符,默认为空格键 |
继续上面的例子,需求为:
- 列出每一行的账号
- 列出目前处理的行数
- 说明该行有多少字段
[release@api_02 ~]$ last -n 5 | awk '{print $1"\t lines:"NR"\t columns:"NF}'
release lines:1 columns:10
release lines:2 columns:10
release lines:3 columns:10
release lines:4 columns:10
release lines:5 columns:10
awk 命令还有更多高级的功能,此处就不做介绍了。
crontab 配置的基本使用
crontab 配置的规则是:
minute hour day month week command
其中每个字段的含义如下:
minute:分钟,取值范围:0-59 之间的整数
hour:小时,取值范围:0-23 之间的整数
day:日期,取值范围:1-31 之间的整数
month:月份,取值范围:1-12 之间的整数
week:星期几,取值范围:0- 7 之间的整数,这里的 0 或 7 代表星期日
command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。
特殊字符:
星号(*):表示所有值
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,6,7”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“1-3”表示“1,2,3”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如 */10,如果用在 minute 字段,表示每十分钟执行一次。
常用的一些例子
实例 1:每 1 分钟执行一次 command
命令:* * * * * command
实例 2:每小时的第 3 和第 15 分钟执行
命令:3,15 * * * * command
实例 3:在上午 8 点到 11 点的第 3 和第 15 分钟执行
命令:3,15 8-11 * * * command
实例 4:每隔两天的上午 8 点到 11 点的第 3 和第 15 分钟执行
命令:3,15 8-11 */2 * * command
实例 5:每个星期一的上午 8 点到 11 点的第 3 和第 15 分钟执行
命令:3,15 8-11 * * 1 command
实例 6:每晚的 21:30 重启 smb
命令:30 21 * * * /etc/init.d/smb restart
实例 7:每月 1、10、22 日的 4 : 45 重启 smb
命令:45 4 1,10,22 * * /etc/init.d/smb restart
实例 8:每周六、周日的 1 : 10 重启 smb
命令:10 1 * * 6,0 /etc/init.d/smb restart
实例 9:每天 18 : 00 至 23 : 00 之间每隔 30 分钟重启 smb
命令:0,30 18-23 * * * /etc/init.d/smb restart
参考资料
linux 卡顿怎么排查
《Linux 鸟哥的私房菜基础学习第三版 –12.4.2 章节》
原文链接
https://tsmliyun.github.io/2019/10/16/ 一次定时任务配置错误引发的思考 /