告警是对监控结果的一种展示,是快速定位、解决问题和阻止事态恶化,挽回损失的神兵利器。要想实现好的告警,需要有全面的监控,恰当的告警策略和及时的响应措施。好的告警策略可以用八个字概括“有错必报,无错不报”。
这里要探讨的问题有五个:
告警淹没
告警发给谁
告警等级
告警传递方式
告警内容
**告警淹没
**
告警淹没是一个很严重的问题,它的主要表现是频繁告警,通常导致重要的告警淹没在一堆无关紧要的告警之中,也会导致团队成员对告警的重视下降。好的告警应该做到,每一次的告警都是有的放矢。频繁出现告警只能有两个原因:第一,项目质量,或者说工程质量实在太低,以至于一直出问题;第二,许多告警都是不必要的,无关紧要的,仅仅是一种通知性质的,甚至团队成员只是看一眼,并不执行什么实际动作。
就第一个原因来说,这么多告警,并不能称为问题,因为它并没有误报,反而是很切实的履行了责任。而第二种情况,则要复杂许多。出现第二种情况的原因有许多,最主要是告警规则设定不合理。告警规则的设定要结合具体的业务来设定。但是告警规则如果设置的门槛过低,就会导致告警频繁,相反,设置的太高,就会导致漏报。这其中尺寸很难把握。还有一些告警仅仅是通知性质的。这种告警通常出现在一种情况下:某些时候,我们在写代码的时候,就知道这里可能会出问题。比如说,调用三方的服务,每一次调用都有可能失败,但是失败的原因有许多种可能,例如超时。超时一般在负载大的情况下会出现,这时不会被认为是什么大问题。因此可能出现在业务高峰期,超时频繁的时候,告警告了一大堆。
那么,对于前面举的超时的例子,是否需要消除这些频繁告警?答案是需要的。实际上,无论出现哪一种情况,都要努力消灭。因为不论在何种情况下,频繁出现的告警都是不正常的,这件事本身就是一个问题,应该得到重视。
在第一种情况下,只能从根本上提高工程质量才能解决问题。
在第二种情况下,可以在现有基础上逐步提高告警的门槛,但是这个要小心谨慎,因为这可能导致漏报,而原则上是多报比漏报好。还可以设定更加细粒度的告警。这条建议看上去有点违背直觉,因为更加细粒度的告警会导致更加多的告警,实则不然。举个例子来说,某一个东西A,它的值在超过5的时候就告警,而某一个东西B,它的值在超过10的时候告警,如果粗粒度告警的话,就低不就高,那么当B超过5的时候也会告警,而细粒度就可以避免这种麻烦。最后一种解决方案是,告警只发给特定的人,它可以发给一个人,也可以发给相关的一小部分人。这就涉及到下一个问题了,告警发给特定人,还是发给全部人。
**告警对象
**
这里的告警对象,是指告警被告知人,也就是告警所知会的人。还有一个概念,就是告警关注人,意思是看到这个告警就会采取一些措施的人。
按照敏捷开发的原则,应该是所有的成员都应该关注所有的业务,所有的代码,因此也就是需要将告警发送给所有人。这里要考虑的就是,是否有这个必要。
我的答案是看团队情况。
先来比较一下发送给全部人和发送给关注者的优劣。发送给全部人的好处有:在关注者没有注意到的情况下可以提醒一下;在关注者没有办法处理告警的情况,可以有人能够尝试处理;强迫大家关注别人的业务;避免问题被偷偷修复以至于团队毫不知情。坏处是:被迫关注别人的告警,导致告警频率上升,忽略自己的告警;削弱告警的重要性。
我认为,在团队成员合作默契,相互之间都熟悉对方的业务,熟悉对方的代码的情况下,发送给全部人是合适的。但是在达不到这个条件的时候,没有必要发送给全部成员,而仅仅发送给关注着就可以了。坦白来说,我认为国内的团队大部分是达不到发送给全部人的那个苛刻要求的,这个要求可以稍微放松一点。如果一个团队能够做到严格遵守开发规范,每次需求讲解都全员到场并且基本理解,那么也是可以发给全部人的。如果再进一步放松条件,那就应该要求团队的大部分成员能够做到。
即便是这个放松之后再放松的要求,我也觉得大部分团队是不具备的。
在发送给关注者的时候,我要反对那种只发给一两个人的做法。可能某一个业务一直都是一个人在处理,别人对此毫不知情,但是这也不能只发给这一个人。同样的道理,如果一个业务一直是两个人维护的,也不能只发给两个人。因为人数太少容易被忽略。这种忽略常常就是关注者都没注意到这里有一个告警。
不论采取哪种方案,我都认为,应该在发送告警的时候,被告警的人之间应该有个优先级。这种优先级是指处理这个告警的优先级。这只是一种对人性的预防。因为如果一个东西很多人关注,没有指定一个优先级的时候,可能导致大家都觉得这个事情别人会处理。而指定了优先级之后,最高优先级的人就带有一份强制的责任去处理这个告警,能够避免一些推卸责任。
**告警等级
**
告警等级是一个很重要的话题。等级划分太细会造成理解负担,而划分太粗,则无法充分体现不同告警之间的重要性。
一般来说,告警有INFO,WARN,ERROR三级。INFO是很少用的,因为它的含义仅仅就是通知一声这里发生了什么,大部分的团队也不会启用这一级的告警;WARN情况好一点,它代表的是这里可能出现了问题,或者出现了一个可以在容忍范围内的错误;ERROR是最为常见的级别,这个级别代表真的出现了问题。
但是在ERROR级别也有许多的差异,有些ERROR要更加重要一点,而有些ERROR就没那么重要。因此是否有必要对ERROR级别进行划分,也是一个需要思考的问题,如果需要划分,那么如何划分也是一个问题。
在划分等级的时候,最为重要的是,确定什么样的告警是重要的,也就是确定告警的衡量标准。比如说,订单量下滑的告警和失败订单的告警,哪个重要,还是一样重要?它们的衡量是以影响用户的数量,还是以影响交易金额来衡量,还是综合考虑?综合考虑之下,不同因素之间占比如何?这些问题,都需要结合具体的业务,和公司的情况来说。
等级还会带来额外的问题。一个等级的告警如果频繁出现,那么除了会削弱整体告警的力量以外,还尤其印象,该等级以下,该等级以上临近的几个等级的告警的力量,这种影响是体现为大幅度削弱这些告警的重要性。告警的数量应该和告警的重要性成反比,也就是越重要的告警,应该越少。总体上是一种金字塔的形状。并且,不同等级之间的告警数量差异应该控制在接近一个量级的地方。
还有一个问题是,按照我对人的了解,在告警等级设计者的眼里的重要性不等于告警对象眼里的重要性。总体上来说,告警对象会普遍高估高等级告警的重要性而低估其余等级的重要性。极端的情况就是“除了最高等级的告警,其余皆不足虑”。
关于制定告警等级,一种对开发人员有利的做法是,按照影响自己的绩效业绩的程度来衡量。该方法和面向简历编程一样猥琐,我对此不方便多说,毕竟我也是一个打工的,上面还有老大。
**告警方式
**
常见的告警方式有:社交软件、短信、邮件、电话。告警方式与告警时效性,告警内容和告警重要性相关。从严肃程度来说,社交软件<短信<邮件<电话。也就说说,最为正式的告警就是电话了。告警方式其实隐含了告警重要性的信息,这点要明确。
在设定告警方式的时候,要注意一些问题。首先,是否会引起告警对象的注意。从这点上来说,越是经常受到消息的通讯方式,告警越是容易被忽视,因此,采用社交软件的方式通知的话,需要额外的辅助告警方式辅助。否则,一个人在短时间内,就容易通过社交软件受到上百条信息,告警会被淹没在这一大堆信息之中;其次,告警能够引起多大程度的重视,越正式的告警越能够引起注意。但是告警的重要性要和告警方式的正式性相匹配,不匹配的话会有一种狼来了的效果,并且会削弱原有告警方式的力量;告警能否及时送达。所有的告警方式,实际上都无法确认告警对象收到了告警。比如,打电话,除非是人工打电话(这当然不可能),那么电脑是无法判断对面接电话的人就是告警对象。
**告警内容
**
优秀的告警内容组织方式,能够让人看一眼就知道出了什么问题,问题出在哪里,什么时候出的问题。因此告警的内容,在描述上应该力求准确、简介,条理分明。按照这种方式,我认为的告警内容有:
级别:能够让人迅速判断问题的严重程度;
问题:这个是告警的最重要的内容,因此应该在第一句话就描述清楚;
位置:即发生异常事件的位置;
详细内容:告警的详细信息;
时间:时间其实是不太重要的,因为告警强调了实时性,因此收到的告警的那一刻,多半都是就在前一两分钟出现了问题。而且从另外一个角度来说,知道时间对解决异常通常并没有多大帮助;
关注者:这应该是一个可选项,因为谁关注这个问题,谁心里清楚。但是在团队成员多,并且默契不足的情况下,还有点用处;
不同告警方式对内容的组织也有差异。距离来说,用邮件告警,那么标题应该包含前三条内容,部分对于时间有要求的,可以将时间附上。剩余的信息就应该组织在邮件正文内了。
我认为一个比较好的标准就是,仿照之前微博字数的限制,在一百字左右就将所有的问题描述清楚。如果不能,那就说明还有改进的地方。告警其实不需要特别多的细节,因为告警实际上起到的是通知和吸引注意的作用,具体的细节,应该是在处理告警的过程中去了解的。
**总结
**
告警是一种下策,因为不管怎么说,告警都暗示出了问题,或者说可能出问题。这只是人类无法掌控所有情况,无法构建一个完美的系统所做的一个补偿性的措施。花费大代价建立一个良好的告警系统是十分必要的,但是更加应该努力提高工程质量和业务水平。