线上故障是一件让人很“紧张”的事情,之所以用紧张这个词,是因为暂时找不到更好的词汇描述遇到时的心态。
对于运维人员来说,出现故障,可能意味着: 失职、麻烦、质疑、加班、绩效、无尽的报告等负面词汇,但也意味着: 机会与挑战。前者大家都好理解,后者也是很重要的,为什么呢?
一、有一部分故障是大家都没有预料到的。
个人对故障的发生是不用担责的,只需要善后就可以这种。
比如机房突然断电了这种大故障,来电后各种毛病就出现了,开不了机、服务启不起来、启动顺序又不对、配置丢了、网络不通、数据异常等等。
这种情况就非常锻炼人啦,只要出现过一次,一般你之后就会对此项目的全局掌握比较清晰了,并且一般遇到这种大场面,也正是展示你台下十年功露脸的最好时机,但可遇不可求。
小故障当然也有学习的价值,遇到得越多,对经验的提升和以后对问题的全面分析能力都有帮助。
二、有一部分故障是个人操作失误导致的。
我们经常说,人总是会犯错的嘛,但这样自言自语说多了后就会让人产生懈怠、疏忽,经历或个人导致故障后,成长更快。
说一个小故事,我在之前一个项目组时,几乎每个人都有造成过线上故障,于是一旦新人来后,我都会笑着给新同事说,不要怕故障,我们都等着看你表现啦!
一般来说大家的心态都是这样的: 刚接触时(小心翼翼),一段时间后(肆意妄为),在触发故障后(后续做事会不自觉地考虑影响面,对大事很谨慎),希望新入行的同学们早日迎来自己的专属故障然后突破到第三阶段吧!
三、不破不立。
老板和业务方一般对运维的主要诉求就是稳定,平时这也不让动、那也不让动。
自己发现个隐患、提出想主动修复,一般得到的答复有: 写个方案研讨吧、节后再看看、你找谁再确认一下、有空大家再开会讨论、下期项目再搞吧等等等。
但如果是故障期间,你说不这样搞就恢复不了、或者不搞就算恢复了也坚持不住一天,大家就会空前的支持你。
我很早前实习做网工的时候,办公室接入有4条电话线,有2条不通,但交换机上和房间内的各种走线太乱根本找不出线来,经常有投诉,但真要去拆开理线时大家又不配合。
某天我实在气不过,于是把几条线都悄悄拔了,大家各种支持协助,于是很快就理顺了那一坨网线和电话线,美滋滋~。
现在想起来当然还有更恰当的办法,也肯定不会建议谁主动这样干。但如果是故障已经不可避免发生了,那能争取一下还是争取一下吧。
故障的发生是不可避免的,根据墨菲定律,有可能发生就肯定会发生。本文所说的故障,主要是指计划外事件所触发的故障,普通割接变更窗口时间内触发的问题一般不算作故障。
主要是为了说一下关于故障需要注意的地方和建议做的一些事情。
本文就按一般的时间线来走,粗略分为这三个阶段:
熟话说有备无患嘛,做足准备是必须的,这一阶段主要内容就是做准备工作。
包括例行巡检和突击巡检,重点是了解系统当前是否存在问题。
很多地方的巡检已经变成了很随意的形式了,要么就是给个万年不变的脚本让一线人员上机去跑一下、生成个空报告,或者干脆就外包出去让一些看似专业的厂商的实习生对一些通用中间件啥的来走个过程。
个人觉得此阶段很重要,应该由核心专家团队来进行,太忙的话一季度或半年一次总行吧。
监控系统的三个主要作用:
一定要有集中化日志系统,将各个主机、组件的日志后汇集到一个地方进行查看。
否则排查时,开十几个窗口到处找日志看就很低效和麻烦了,而且集中起来后一旦什么组件因故障不吐日志了,也很容易确定。
如果暂时没条件,最次也要将所有的文件日志同步到一个地方来,比如集中的syslog服务,ELK日志收集等都可以考虑。
通过对架构进行分析,评估可能存在的故障点。 关键设备的性能不足、设备老化等显性的隐患;
配置存放在易失性缓存里面,共享资源隔离程度不够,全流程涉及的网络节点过多等隐性隐患;
监控系统自身的可用性,告警方式和路径是否单一,如果监控系统挂了,或告警路径断了呢?
业务分析,每次特殊性业务开展前进行评估。 年终大促能不能顶住,新增接口的性能情况,数据迁移时能否在规定窗口期间完成,新增的数据空间够不够等。
按各自的职能和代表立场进行分配,搭配出一个最佳人员协作名单,一般的人员分类方式有:
个人觉得,这中间最关键是担任“路由”角色的人,一是能不能隔离外部的干扰信息,并且把有价值信息带进来,二是能将切实有效的方案传递上去给领导去拍板很重要(有些影响大的措施,很多人只能私下说,却不敢公开说)。
先有一个共识性的标准,确定在故障发生时各方需要投入的资源,不至于“草木皆兵”又或者是“狼来了”。
常见的分法: 一般故障、严重故障、重大故障,小、中、大,I级、II级、III级、IV级。
预案的要点:
常用命令集合、常用SQL、长命令,常用小工具、脚本、密码本、通信录、业务架构图、网络拓扑图、设备位置表等等放在一个方便的地方。
经常发生的一些尴尬事情:
电脑不可靠,关键时刻开不了机、软件打不开、键盘鼠标又坏了,这些事情时间长了就肯定会遇得到。解决办法:
网络要么慢、要么卡、要么干脆连不上。解决办法:
大家提前说好,优先用什么方式配合,免得配合上出现问题,一般规则:
在公司的相关人员都抱上笔记本就近坐到一起来,最好能霸占住一个会议室;
远程则一定要拉一个在线会议,主要人员操作时投屏,非主要人员不说话时静音;
外部专家电话接入时,一定要免提扩音,避免转述时出现歧义(个人经历过此教训);
在长时间排查处理时,要有一个行政协调人员,一般是项目领导或“王见 场”负责人担任。
负责打饭、订饭、泡面、协调会议室、上报进度等辅助工作。
(个人经历,某次众人集中排查到深夜,我突然有了一个点子,需要A配合,结果他去泡面了,A回来后正要开工时,需要配合的B又去泡面了,最后等人齐多耗了20分钟)
比较常规一些的就是生产环境切换演练和安全演练了,再升级一步就是测试环境内专家出题进行演练,终极方式当然就是生产环境进行破坏性演练了。
故障处理的基本流程:上报->快速恢复->排查->处置->观察确认。
上报和抢修应该是不冲突的。
先报再查很有必要,经常遇到一些同事发现故障了,认为需要先观察一下,要收集一些信息后才知道上报时如何表述。
我是觉得没必要,顺手一个电话,或发个消息,说一句“当前时间,发现XX现象,疑似XX故障,速支援”,并不耽误排查。
先上报以便快速初步定一个故障级别,然后事中每隔一段时间或进行关键操作后,也应该上报一下。
线上问题应先求快速恢复,再去分析原因或根治措施。
我也遇到过很多次故障,一群人慢慢排查分析,找出一个解决办法给领导或客户,拍板后就做,然后再看有没有效果。
其实这种方式很不好,就如同本来就有主备环境,出现故障的时候,先讨论10分钟确认是否有必要切备机,一样很尴尬。
备机难道不应该是随时可切的吗?如果不能随时切换那就说明这不是合格的备用环境。
有人会说,我都没有排查,不知道问题原因,拿什么去解决呢?万一切换后也没效果怎么办呢?
所以快速恢复这一步能否进行的关键就靠预案了,良好的预案应该标注有:A现象对应A操作,B现象对应B操作。
一线或应急团队的人员只要熟悉预案,很快就能确定下一步该做什么。
有人可能又会问了,那要是把可能发生的每种现象都列出一个操作来,几百上千条谁能记得住?翻目录都得2分钟吧。
但实际情况下,应急操作最多也就三五十条,一是因为很多现象都可以用同一个方法去解,二是内容再多就需要分工了。
比如我之前所在的项目,如果不是业务量的问题,那最通用的也就三板斧,先回退、切备环境、再切数据中心。
关于切换:
排查流程主要也就两个点:收集信息->分析
故障排查注意事项
优先进行最方便最快捷的检查方式。
那种需要去执行复杂命令、等一会儿才能出结果的慢动作可以放后面去操作,或者由其他同事并行去做。
收集到的信息更多地用于考虑排除问题。
收集到的信息既要考虑问题可能在哪,又要用于排除问题应该不在哪。
比如出现未知故障,先打开网站首页,能打开则入口一侧没问题,打不开多是入口节点或链路的问题,从而缩小了排查范围
注意人的局限性
首先是要确保参与排查的人员对这一块内容熟悉,然后是小心他太熟悉了。为什么这么说呢?
因为人总是会倾向去做和相信自己熟悉的事情,比如突然数据库连不上了:
开发人员倾向于去分析代码,看看是不是如逻辑问题导致的线程或锁不释放等,DBA倾向去排查数据库自身,主机运维第一时间会去看系统日志和性能监控数据,网络运维第一时间想到的是登交换机看端口状态、流量、抓包啥的。
但团队里不是所有人都同时在线的,如果此时就一个人在值班,恰好他排查时又发现了一点和自己专长相关的可疑点,可能就会带偏大家。
我以前就常遇到这种事情,故障排查时某人说我发现原因了,约1分钟能解决,我们舒了一口气,开始配合,1分钟后现象还在,一会另一人又发现原因了,改为配合他,这样反复几次才真的找到故障原因。
所以在排查时要综合考虑意见,多个方向和措施并行突破。
排查前要先提问
一问:哪个节点?
有问题的是什么东西,某个实例或某一类实例、某一类业务?
二问:什么范围?
定位到某个实例、某个主机、某个集群、某个中心
三问:什么程度?
量级变化,如CPU增了多少,网络慢了多少,业务量增或减了多少。一般来说,如果业务量没有超过历史最大峰值,则大概率不是自身性能问题导致。
四问:什么时间?
是否是业务高峰期,是否是关键定时任务执行的时间,是否是在常见的变更日(前公司集中在星期二和星期四进行变更)。
五问:是否有什么人工例行计划忘记去做了?
如:域名续费、https证书到期更换、密码过期、手工迁移数据、云实例或宽带到期续费、忘充电费(真有,我在第一家公司时自建的小机房用的是民电,行政忘了去充电费直接就停电了)。
加密证书或授权过期,现在很多证书都是有有效时间的,比如https证书一般一年一签,如果没有自动更换机制很容易忘。
给上下游的或上下游给的自签证书,一般都是设置5年10年,虽然很长,但也是会到期的。
六问:前后都有什么动作?
自己系统的业务和环境变更;
上下游及周边业务系统的变更;
底层设施变更,如网络设备和策略、存储设备、云或容器平台等;
故障发生后其他人都进行了哪些操作。
用于排除了无效修复措施,记录一下或许一会儿还要进行回滚。
七问:现象有什么规律?
比如每5分钟应用卡顿一下,CPU使用率波动起伏有无规律,每天几点固定出现,做某某操作必然触发等规律。
八问:能否重现?
考虑一下测试环境是否也能重现。
九问:最近有什么外部事件?
先靠经验排查,再靠数据排查
经验排查:最了解这个系统的人,“王见 场”人员、开发人员、产品使用人员,他们可能看一眼就知道问题在哪了;
数据排查:就是先把已经提供的数据都看一遍,然后通过执行一些动作获取一些数据,通过数据进行分析。
通过数据排查时
需要的数据
基础的数据分析方法
将正常和异常进行对比,例如把之前正常的监控图表和当前故障点的图表,重合起来看看看差异是什么。
关联分析,分析多个故障之间存在的关联分析;
比如主备机房连接数据库都报网络错误,那就说明跨机房网络应该没问题;
又或者故障投诉已经找上门,但却没有收到告警,就可能是网络问题导致告警发不出来了。
排除法:某某指标正常,就证明不可能是某几类原因。
无法定位问题的故障该如何处理?
其实只要不能很快就定位问题,一般也都是这样几板斧先临时解决着。
备份和保留原“王见 场”
将系统当前状态信息或环境变量记录一份,需要修改的配置文件和数据也拷贝一份,以方便验证无效时进行回退,以及事后写报告时做为材料。
但是很多人其实都没有这样的习惯,要么是确实忘了,要么是赶时间觉得没必要,要么是觉得信心满满觉得一把能成,这样肯定是不太好的。
但比如服务启动异常,要来回改很多次配置文件,每次操作前都手工备份一下很耽误效率的,那有什么好的办法吗?
解决办法当然有:
有定时备份任务,定期自动对配置文件做备份;
全局配置文件,比如放置git上,每次都从git上改,就不用单独去备份了;
putty、XSHELL或CRT都是可以记录屏幕内容至文本文件的,把自动记录日志功能开启。
以后任何时候改线上配置时先 cat 一下文件,只要内容在屏幕上出现过就行,要恢复时从日志文件里面去找,并且事后看看自己的操作记录也可以很好地梳理清楚处置过程;
当然 windows也可以使用自带的 psr 或者其它录屏工具录着,有备无患。
验证
理想故障处理一般都是“收集信息->假设分析->验证->实施”,条件具备就应该先验证再实施,没有条件的话多个人一起讨论一下也行。
应该避免“突然想到啥,就立马实施”,如果故障感知不明显且时间允许时,最好是能先在测试环境验证一下再上生产操作。
我举以前遇到一个例子:
某次线上故障,分析了一会儿得到了正确的解决思路,但操作起来要几十步,次数多、命令长、中间还需要间隔等待什么的。
于是我同事就决定写个脚本,主要步骤单独列出来执行,重复步骤做成循环执行,这样的想法是很好的。
为了赶时间就直接在生产服务器上写了一个几十行的shell脚本,但真执行下去,就出大事了。
先是shell脚本的部分行语法不对,导致部分内容执行了,部分没执行,然后发现部分文件路径不存在(因变量原因),再发现这几台服务器环境其实是有差异的。 完了,于是更大的麻烦出现了。
所以劝大家有条件还是每步进行一下验证为好。
处置时的重点
确认是否真的恢复了,如果没有恢复,那就再回到“排查-修复”阶段。
故障中期的其它要点:
有预案的先拿出预案来,快速确定是否可以靠预案进行;
避免独自排查,排查和处置时及时将有用消息通知出去,积极请求外部的技术和行政支持;
需要判断当前现象是否为最严重程度,有可能你发现的只是苗头,更坏的情况即将出现。
例如: 备份服务器故障,导致主库的数据未能及时迁移走,2分钟后主库就要满啦~
当然不是就这样简单的结束啦~,痛苦才刚刚正式开始啦~
要点:
其它注意事项:
严肃的事后形式
比如误操作,虽然不一定要进行什么实质性的处罚,但开个小会内部检讨一下还是有必要的,不然不仅当事人自己不重视,其他同事以后也会不重视。
(PS: 我们这虽然不做检讨,但默认故障之后的“故障报告+几十次修改+十余次的故障报告会”都需要当事人主导,也相当于脱了层皮。)
有产出
既是个人的经验积累,也是公司的知识积累,对新人培训及熟悉环境很有帮助; 积累到一定数量和时间后,针对top3的故障进行根治; 对完善日后的各项应急预案、监控体系做为输出材料依据很有帮助。
好了,基本上常规的故障处理流程就结束了,说一些其它相关内容吧。
个人在这几年常遇见的以及一些罕见的故障类型梳理:
硬件宕机、需要停机进行的配件更换(一般是磁盘、内存)、UPS坏了、机房空调坏了、机房进水、机房缺水。
网络一般就是交换机端口坏了,网线接口松动,错误配置导致网络形成了环路,网络设备内部系统有BUG,ARP表不够,网络黑白名单、ACL白名单等等。
(PS: 这个机房进水和缺水还能真能遇得上,去年郑州暴雨,机房进水不就发生了吗,机房缺水(缺少干净的空调用水)也发生了。)
误操作删除或修改了数据;
高峰期进行 dump/Load 或跑大SQL影响了性能;
在线DDL操作影响了性能;
程序bug导致事务长时间未提交,线程越来越多;
各种奇怪的锁;
网络存储的性能问题。
网络存储只要不是独占就很可能出现被别的系统争用资源导致的性能问题。
尤其注意NFS。
一般现在操作系统都比较稳定,硬件不出问题的话开机10年都没有啥问题。
我之前维护的设备,5、6年没有重启过的非常多,只要正确配置好刚上线时不出问题,那就很难出问题。
能出现的主机系统故障,多数是人为导致的。常见情况:
举个我以前的例子,甲方给的安全加固手册要求把passwd文件通过 chattr 加只读权限,又要求密码3月自动到期,并且不允许root用户远程登录。
这样做的效果是什么呢,安全加固做完了,当时没啥问题。
3个月后某天密码到期了,普通用户登录时就提示要修改密码,输入新密码又提示没有权限,想改权限呢又登录不上主机,死循环了。
当时我是怎么解决的呢?我悄悄潜入机房(正式流程太长,紧急流程又联系不上关键人,机房在同一栋楼),推个显示器逐台修改。
CPU使用率高、负载高、内存使用高、磁盘使用高,基本上和主机操作系统没啥关系,优先排查应用。
例子: 某次发现一个接口调用特别卡,于是ping主机发现延迟特别大(上千ms延迟),于是找网络的人员排查,许久没结果。 又找主机的人排查,发现CPU负载特别高,排查许久发现负载高的原因居然是内存使用率高,内存高是因为slab里面的dentry项太多。 绕了一大圈最后回来发现是还是因为业务程序有bug,有个功能会高频创建打开随机文件名导致。
比如以前使用el5时iptable的ip_conntrack链路跟踪表总是打满然后拒绝连接,改了配置后一重启iptable就恢复原值,遇到几次才发现。
又比如内存的使用机制问题,明明还有剩余内存就使用swap了。
一般多是线程泄漏、内存泄漏、连接数太多、日志吐太多、程序BUG。
前几年有个通过java中间件weblogic的反序列化漏洞进行挖矿的事件,原理就是利用漏洞先攻进来,杀死全部JAVA程序,并下载远程的一个程序进行挖矿。
我们当时的客户是个国企,出网访问都需要网络侧开目标白名单的,所以没有真的挖上矿。
但这个java程序总死我们却找不到原因,一开始没往攻击这方面去想,总以为是不是自己程序哪有啥bug,什么回退版本、改代码、抓包分析啥都做了也没效果。
直到几天后我把一段特殊的痕迹放到百度上一搜,几乎惊掉了我下巴,居然还能真遇上攻击,临时做了个URL黑名单然后再升级补丁。
所以遇到灵异事件时,最好也先想一想是不是攻击导致的,还有注意DDOS攻击也是常有的。另外羊毛党也要防一下的。
故障简述:三五句话说明这次故障事件;
故障过程:什么时间发生了什么,做了什么;
故障影响:对业务造成的影响,量化指标。
比如影响了XX时间至XX时间的多少笔交易,影响xx用户数,影响了N个上下游业务系统;
故障原因:详细列举故障的根本原因;
改进措施:短期临时措施,根本解决措施;
其它信息(选填):比如责任方、责任人员、故障定性、损失金额、人员处置措施、人员管理改进措施等等。
监控系统发出告警:当然覆盖面、采集时间要合理;
主动巡检分析发现:没事时多看看监控系统指标数据,看看日志文件总会有啥新发现的。
比如某指标异常波动,但还没触发告警阈值,日志文件吐了点新内容,但没有被以往关键字匹配上。
外部人员发现通知:用户投诉、上下游和周边系统告知等。
个人觉得就 “通知数量和重要程度”来说 监控系统发现占比80%,主动巡检发现占比10%,外部通知占比10%。
距离写个人第一篇博客,居然已经过去8年了,希望自己能重拾初心,继续热爱这个专业。
|