作为一个惹出过和处理过一些严重故障的人,我仍然觉得要做好稳定性,最难的并不是技术,或者更准确的说,技术上在怎么做好稳定性,从代码到设计到变更,都有全面的指导思想和原则,包括大家如果去看很多的故障复盘,在改进措施上基本会看到各种类似的话,但这些思想和原则要落地好,是很复杂的话题,有能力要求,还有更重要的是投入要求,而且并没有银弹级产品说做某件事,或安装一个什么软件,就可以保障稳定性了。
先简单说说技术上,然后再来说为什么难的不是技术。
代码层面关于稳定性的指导思想
我之前说过是不是优秀的程序员,代码是最好的证明,优秀的程序员的最大差别其实就是在代码的鲁棒性上,而这个一方面需要极强的能力,看看netty的代码里对各种边界情况的处理就知道要求多高,另一方面则是需要有投入的保障,否则都在赶进度,自然是会把鲁棒性相关的代码放一边,毕竟很多时候这些代码还挺难体现价值的。
代码要写的鲁棒,很关键的几点:
1. 对输入的边界的控制,确保输入是符合自己的预期的,而不只是文档上写的一些对输入边界的约束,例如最典型的故障是批量操作型的接口,由于批量操作的量超过了预期,直接内存溢出等;
2. 对使用到的API需要有深刻的理解(包括实现原理、代码细节),这个其实对程序员的能力要求是非常高的,这里用到的API包括了语言本身提供的,这也是为什么很多时候大家觉得面试的时候问的非常的细,好像这些技能对实际写写业务代码也没什么影响,但其实只有这样,才能知道各种情况下的状况,从而在真正出故障的情况下能快速处理;
3. Fail fast,不管什么情况,以保障代码能正常运转是最重要的(最简单的标准是别把资源耗尽或crash),在碰到意外情况下,尽快往外抛出错误是最好的,当然,这个主要是对在线型业务而言。
设计层面关于稳定性的指导思想
在设计层面,关于稳定性的指导思想,很关键的几点:
1. 强弱依赖识别,对弱依赖的地方,确保有各种降级策略,当年阿里某关键系统,就是在做好这点后,稳定性提升了N个档次;
2. 自身能力保护,一定要对自己系统的能力有清晰的认识,例如通常来说在线业务系统的指标通常是每秒处理的请求数,在超出能处理的请求数的情况下,需要尽快fail fast,在线业务做堆积是不好的,容易出问题,像Nginx之类的不一样,但也会对堆积程度有个边界控制;
3. 容灾能力,这个从集群化、到同城多活、再到异地多活,其实都有各种成熟的案例和相应的方案。
对于架构师而言,在设计层面,对稳定性的投入的平衡是很重要的,这个和代码层面还不太一样,代码层面有追求的程序员很多时候自己就会花时间去做到,但设计层面很多对稳定性的投入可能是非常大的,所以会是更大的决策。
变更层面关于稳定性的指导思想
专门说变更,而不是整个运维层面,是因为通常故障和变更会有关系,运维的话比变更这个话题大太多。
在变更层面,关于稳定性的指导思想,很关键的几点:
1. 强制灰度,毕竟能灰度,相对来说就能更好的控制故障的影响范围(另外一个词是爆炸半径),这一点呢,我觉得只要不完全是通过系统去做的变更,就很难完全做到(人很多时候还是会容易信心爆棚),非常非常核心的系统,其实还是需要有强制流程规则及很重的惩罚规则的,就算是以影响效率为代价,毕竟有些时候慢才是快;
2.可监控以及可回滚,没有监控,就完全没办法知道变更后的情况,可回滚通常是变更一旦出问题,最好用的招,但确实也会难免碰到无法回滚的变更,那样类型的变更就要高度谨慎了;
3.在故障出现时尽快恢复,而不是解决故障,在保留一定的现场的基础上,尽快的恢复问题比查问题重要的多,例如大家很多时候看到最有效的处理故障的方法可能是重启,有同城双活、异地多活的通常最有效的处理方法是切流量等。
做好稳定性,难的不是技术,而是
大家可以看下,是不是在很多故障复盘的改进措施里,都会重复看到上面的影子,说明其实指导思想、解决方案是不缺的,技术上真的没有那么的难,想当年淘宝稳定性很差的某一年,新任CTO上来后把稳定性列在了第一考核指标,三个月后淘宝的稳定性就提升了N个档次。
但难就难在没有银弹,只能靠大量的细节来落地做好稳定性这个系统工程的事情,这意味着的是大量的投入,能不能在稳定性这件事上保持持续的一定的投入,甚至当成做业务功能实现一样的必须的投入,这才是真正做好稳定性最难的,毕竟就算有指导思想、解决方案、能力,但没有相应的投入,那自然只能有一定的取舍,最终呢,总是要还的。
很多做过稳定性这事的人都知道,做这个事情最麻烦的是很难被认可,做的好,不出问题,不懂的人不知道你做了什么,出了问题的时候觉得你到底做了什么,所以会看到很多公司都是运动式的做稳定性,一阵一阵的。
要解决这个问题其实挺难的,我看到做的好一些的,基本是因为稳定性对业务而言是致命的,例如某些行业,稳定性出问题,业务基本就没法进行下去了;还有就是某些处于非常激烈竞争,但又有关键时间点的业务,例如外卖。
只有把稳定性当成业务的功能实现一样,有相应的人员配备和投入,例如做一个业务可能需要多少人,相应的稳定性这块也固定投入多少人,你说到底多少比例合理呢,其实也说不太清楚,但这种简单粗暴的方式其实是最有效的,当然,是不是要把稳定性上升到这样的高度,也需要根据业务的性质、业务所处的阶段来具体判断,以及有这样的投入的情况下,怎么去评判相应职责的团队也仍然是个很复杂的话题。