您的位置:首页 > 其它

一次由脚本升级引发的故障

2012-06-10 02:08 260 查看
在日常开发及运维工作中,可能会遇到各种各样的程序故障。

大部分故障都是由代码bug或操作不当引起,下面就9月2日发生的一次脚本升级故障说起。

最近对进程监控相关脚本进行优化,周五在几台机器上测试OK。考虑到这次修改并不涉及主要逻辑变更,还是选择了下班后更新脚本。

晚上十点多钟的时候接到运维同事打来的电话,反映有好几台机器上的log_monitor.pl进程占用大量系统资源,严重影响业务程序运行。

考虑到晚上刚刚对脚本进行升级,第一反应当然是更新后的脚本问题,于是马上中断正在进行的升级操作,对代码进行紧急回退,并kill所有正在运行的脚本。

脚本全部回退并结束所有正在运行的进程之后,终于不再出现系统资源占用过高的机器,这才开始彻查产生故障的原因。

这里监控脚本消耗系统资源主要表现在下面两个方面:

1、监控脚本本身占用大量内存,最高多达7.1G。

2、部分机器上拉起大量logclient进程(上报远程日志的客户端程序),消耗大量系统资源。

经反复核查测试,发现问题并非由新脚本引起,而是出在脚本升级过程中。详述如下:

一、更新前的监控脚本包含以下处理逻辑:

1、脚本每次执行完,都会上传本次执行的监控日志到远程logserver(新脚本已取消该逻辑)。

2、上传远程日志时会调用get_main_ip.sh获取本地IP(脚本执行前会检查该是否存在)。

二、新监控脚本升级过程如下:

1、清理conf、bin、tmp目录下所有脚本及配置文件,保留log目录下所有日志。

2、用新脚本及配置文件覆盖对应目录。

三、产生问题的场景及原因分析:

当新脚本升级的时候如果老脚本已被调起,则:

1、老脚本在上传监控日志时找不到配置文件,从而尝试上传整个监控日志内容,导致大量logclient进程被拉起。

2、上传远程日志的时候,如果get_main_ip.sh文件被删除,会触发一个隐含的递归调用消耗大量内存。

注:上面两种情况在更新后的脚本中实际都已消除,新脚本不再上传监控日志,也消除了隐含的递归调用。

四、规避此类问题的方法:

1、脚本升级时,采用先清理原有文件、再杀原有进程、最后覆盖新文件的方式。

2、避免多个处理过程之间隐含的递归调用。

3、增强代码健壮性,加强对运行过程中类似文件被意外删除等异常情况的处理,避免出现不可预料的后果。

五、从规范上保证程序健壮性:

1、对于公共脚本(在所有机器部署的),代码至少由两个人进行二次验证。

2、代码升级前必须灰度。

3、对循环中的敏感操作进行确认(如fork,发送告警,拉起其它脚本等)。

4、对需要频繁执行的程序,增加不可重入的逻辑,避免程序同时运行多个实例。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: