背景
某业务人员反应系统登陆不上去,于是程序员自己试着登陆系统成功了,心里很自信的认为“我的代码没有问题”,便让业务人员再试试。然后业务人员是登陆成功了,但是整个系统用起来很卡,这下程序员意识到是系统的问题了。
排查步骤
因为刚刚上线了新的功能,想到了配置了定时任务,可能是定时任务配置错误,导致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鸟哥的私房菜基础学习第三版–12.4.2章节》