报警

10年前我问过别人一个问题:这个逻辑上理论上不可出现空值,要不要进行非空判断呢?

现在这个问题终于有答案了:要进行非空判断,判断如果问题发生则立即发出报警,报警中明确标出,如果这个报警被触发,一定是代码里有bug,请立即处理!


类似这种理论上不应该触发的分支、或者触发了资源的水位,在代码中应该做报警处理。所谓资源的水位是指:

比如数据库当初是按照tps3000来申请资源,达到tps2500就很危险了,应该考虑X轴、Y轴、Z轴拆分之类扩容措施。

再比如磁盘空间只剩余20%,这就该检查一下是否异常情况导致日志过多、或者业务增长太快,机器配置需要更新,日志设置需要优化等。


 

监控

有些问题不需要使用推送(push)这么极端的方式,属于重要不紧急,可以在每天固定时间,或者自己有时间的时候、有需要的时候自己进行check。这种通过拉取(pull)方式来对应的问题一般通过监控来呈现。下面的配图不是有意给脉脉打广告哈。只是觉得这个四象限工作法的小帖子确实不错^_^。

注:本人就职于美团,并不就职于脉脉。因为是脉脉KOL,所以会偶尔收到些脉脉的小礼物O(∩_∩)O~


美团点评这边用CAT,可以侵入式在程序里灵活埋点。我每天早上9点多到公司第一件事就是查看自己负责项目的CAT有没有异常,异常包括:failed、耗时长、长尾请求,和自己最近有过发版的地方的指标。


有些监控不一定是以监控的形式,比如下面是定时任务的执行状态。如果状态是failed,就需要查查问题原因了。


 

数据报表

调一调焦距,再宏观一点看。我们需要通过数据报表来分析系统、业务状况,看有哪些需要改进的点。看报表的关键是在看之前要自己有一个心理预期。让预期数据和实际数据做一个对比。这也是junit测试assertEquals的原理。


举个例子:

业务申请资源时,申请服务器成功时会触发incUse,释放服务器成功时会触发decUse。每个小时数据都是下面这样的:申请服务器几百个,释放服务器十几个,哇,一天要消耗近1万个服务器。资源很快就耗尽了吧?这符合预期吗?


再举个例子:不比不知道,看看平均耗时就知道谁做的烂。


在报表中重点数据要用不同的颜色或者特性符号进行标注方便引起注意。


复盘

复盘在工作和生活中用的都很好用。

昨天男神发微信给我说学校群里通知说考试了。小鲜肉没在家庭群里晒卷子呢,肯定是没考100啊。果然,晚上我俩回到家看到桌子上有份99分的试卷。作为一个中科院心理学毕业的研究生,我第一个反应:别给孩子贴标签,说马虎、不细心之类的。周末咱们做个复盘。


复盘原本是围棋术语,在下完一盘棋后,双方棋手把对弈过程重新摆一遍,总结过程中的亮点和不足,对局中招法的优劣与得失,并从中寻找提高水平的方法。

何时复盘?

小事及时复盘,大事阶段性复盘,项目结束后全面复盘。

如何复盘?

复盘四步曲:回顾目标、评估结果、分析原因、总结经验。

在回顾目标阶段,建议使用SMART原则。


下面是一个复盘例子:

我在美团基础架构部参与公司的容器化项目HULK。HULK其中有一个子项目:调度系统SHIELD,目标是负责容器的整个生命周期。就是从容器创建到销毁的整个过程。根据目标来制定我们的SLA是扩缩容成功率,即创建和销毁容器的成功率。

回顾目标

在项目启动之初,我们SLA很不稳定,在18年底,也只有97%。当时我们制定的目标是在19年春节结束之前达到周成功率99%;19年4月前达到周成功率99.9%;19年6月前达到周成功率99.95%。

评估结果

从CAT(美团点评分布式开源监控系统)的统计结果来都完成了目标。

分析原因

能够达成目标的主要原因是从目标出发,制定了一系列以目标导向的问题收敛计划,并严格执行。

总结经验

过程中做的好的方面是每一个问题都用了5Why分析法找到问题的根因进行根治。不好的方面是对子模块的指标制定的不合理导致走了一些弯路。具体例子如下:

从失败的数据分析,大概1%的失败是由于资源不足引起的。而资源余量子模块carter的调度成功率却基本维持在100%。出现这种差异的原因是如果资源不足,carter服务应该返回资源为0。这样carter服务实时准确的返回了实际的资源情况,这时候不允许扩容发生,就不会出现失败。而carter服务正常运转,但是返回资源还有余量,让扩容进行到执行真实扩容时才发现扩容失败。

问题的原因是carter的指标出现了问题,不符合SMART原则的Relevant原则,与最终目标的相关性不符合预期。carter的SLA指标应该是:调度成功率*结果的正确率。


如上图所示,调度系统SHIELD将对请求的处理划分为请求层和执行层。请求层处理参数合法性校验、资源校验等校验问题。在请求层拦截掉没有资源还进行扩容的请求是符合系统目标的。这个请求处理算是成功的。但是进入到执行层,由于任何原因导致的容器没有正常创建完成都算作失败的。

所以资源校验的成功率应该定义为是否正常拦截了无资源还进行扩容的请求,即:调度成功率*结果的正确率。

 

总结

发现问题是工作中最重要的能力之一

 

推荐阅读

编写代码的「八荣八耻」- 以用户易用为荣,以复杂歧义为耻

编写代码的「八荣八耻」- 以开关上线为荣,以自信编码为耻

编写代码的「八荣八耻」(上篇)

 

关于作者

一线开发十二年,有日本东京和美国硅谷研发经验。有百余项技术发明专利,目前任美团点评技术专家。有自己的技术公众号「编程一生」。如果您在阅读文章时有什么疑问或者发现文章的错误,欢迎在公众号里给我留言。

项目改进的四个抓手_项目改进