论对上线存敬畏之心

敬畏,是人类对待事物的一种态度。
在我们的一生中,会敬畏人道,会敬畏法律,会敬畏生命,会敬畏自然。有了敬畏之心,人与人之间才能和谐相处;有了敬畏之心,我们才懂得遵纪守法,维护秩序;有了敬畏之心,面对自然苍生,我们才能泰然处之。
曾国藩说:心存敬畏之心,才能行有所止
曾国藩,是我国近代史上著名的政治家,理学家。面对 敬,畏,之心,他曾说过,“敬则无骄气,无怠惰之气”,“畏天命,畏人言,畏君父”。一路走来,他一生都秉持着坚守原则,坚持底线,对人谦逊平和,遇事谨慎从容的人生观,价值观,走向人生的成功,迎来人生的巅峰。
程维说:对上线滴滴顺风车保持敬畏心
2018年9月5日,随着顺风车事件的发酵,滴滴配合相关部门调查。程维表示,滴滴运营如此大规模的移动出行业务,缺乏经验和参照,没有足够的敬畏之心、警惕之心,丧失了安全红线和底线的意识,社交出行的引入也偏离了绿色共享出行的初心。
自此,滴滴痛定思痛,关停相关业务,并马上开始了全方位的内部反思与业务改造,并把“all in 安全”作为滴滴未来的核心战略。
2019年11月20日,经过两年的蛰伏,滴滴顺风车再次扬帆起航。程维说,我们怀着敬畏之心再次出发,希望能为用户的出行提供更多选择,也承担更多的社会责任,努力提升安全,把好的事情真正做好。
时至今日,滴滴不断突破自我,不但在护城河领域再填花小猪业务,而且在“社区生鲜”这样的互联网风口取得了不俗的成绩。滴滴,焕然一新。
由于缺乏对业务的敬畏之心,滴滴从如日中天到陨落神坛。由于重拾对业务的敬畏之心,滴滴从一蹶不振到东山再起。
我说:对服务上线,要存敬畏之心
作为个人而言,我们作为互联网开发一线的普通员工,既比不上曾伯涵这样的人之龙凤,也没机会经历滴滴之于will这样的大落大起。但同样作为个人,我们一样拥有自己的工作,自己的事业,乃至具体到一个一个的服务,面对我们所负责的这些,我们也需要和那些先贤,那些社会精英一样,拥有一颗敬畏之心。
没有敬畏之心,我们写代码随意,上线随便,bug频出,服务不稳。产品质量不高,没有用户粘性,用户不满,反馈频仍,而我们又反过来需要对自己的过失买单,一边要写着写不完的需求,一边还要查着查不完的bug,反反复复,终而复始。。。
我们希望活得快乐,我们希望能够工作的从容,活得从容,哪怕我们只是一个又一个小小的码农。所以,我们要精于我们的工作,要对我们的服务负责,要从对服务,对服务上线怀有敬畏之心做起。
服务上线方法
前不久有幸听过滴滴顺风车的稳定性分享,作为滴滴内部唯一一个经历过生死的项目,我相信其对自己的稳定性总结最为透彻。所以以此为借鉴,分别从上线前,上线中,上线后三个角度总结下我认为应该做到的事情。
上线前
开发阶段
技术选型:在技术选型前尤其慎重,不可敷衍了事,因为一个不经意的选择,可能会造成后期几倍甚至几十倍的问题排查解决成本。比如,当你需要对一个高频调用进行解耦削峰的时候,你选择了redis队列,而不是用的成熟的MQ,看似没有问题,但是在实际生产过程中,redis作为缓存,并不保证数据的可靠性,所以放到redis队列中的消息时常会丢失,而你又无从查起。
代码风格:在正常的开发过程中,往往我们最经常做的最重要的但往往可能也是我们最不能够引起我们注意
地方,就是我们无时无刻不在写的手下的一行行代码。一套质量好的代码,往往不需要写任何注释也能让大家看懂它能体现出来的思路。作为我们所踩着的巨人,前人们已经在写代码过程中为我们总结了一套又一套的方法与思想:23种设计思想,设计思想六大原则等等,甚至有公司内部专门总结的开发手册。但是真正考验的,还是我们写代码的时候是否用心,是否一遍又一遍的咀嚼代码的合理性。只有合理的代码,才是它存在的理由。不过虽然这么说,我想我自己也没有达到这种水平,但是开发工作本身,就是一种给自己不断精进自我的机会,它像务农,像盖楼,像钓鱼,像修行。。。
前瞻性故障处理:有人说,故障处理属于稳定性建设,不是特别应该提前考虑。但是如果在开发阶段就能够尽可能的将隐患考虑进去,这种有效的前瞻性处理,也不失为有意义的。那什么叫故障处理呢?比如有降级,限流,切流等。早做准备的人,也会更早脱颖而出,就比如之前upm突然宕机,不能提供服务,一个基于前瞻性的增加缓存的降级手段,便使得整个部门扛过了这次事件,继续为用户服务。
测试阶段
rd测试:在此,将开发自测也作为了测试阶段的一部分,当然,如果将这个操作放到研发阶段也觉得并无不当。在这个阶段,理想情况下,我们需要为我们写的每一个接口做到单元测试,且测试用例要完善,做这个事情,其实不难,难的是是否真正的怀着敬畏之心把这个事情一直做下去。往往,人最大的敌人就是自己。
Qa测试:当rd测试完,理论上就可以把开发分支的代码合到测试分支,发布测试环境了。在测试环境,qa需要按着需求评审用例将每个场景都测试完整,而作为rd,个人的习惯是全程坐在qa身边,以期望在测试过程中第一时间为Qa同学提供帮助,尽可能快速走完qa测试流程,当然在有些公司,条件不允许,只能等着qa给反馈了。
全链路压测:全链路压测是指基于实际的生产业务场景、系统环境,模拟海量的用户请求和数据对整个业务链进行压力测试,并持续调优的过程。当然执行全链路压测之前,要考虑好两个方面的事情,1,场景是否有必要做压测,比如如果业务的挑战性不在数据量而是逻辑复杂度的话,那可能消耗过多人力资源去进行压测就不是一个明智之选;2,数据模型重建,此又涉及数据可用性,数据脱敏,数据隔离等因素,这些因素不考虑且准备清楚的话,不但不能模拟线上场景,且有可能污染到线上数据。
监控添加
odin监控:工欲善其事,必先利其器,如果线上在跑的服务,没有任何监控手段,就好像山间放着几万匹马,如果没有牧马人一样,那结果肯定是可想而知。所以我们在上线之前,一定要把相关接口关键指标的监控及报警加好,一旦出了问题也能第一时间感知到作出响应动作。
上线中
CR
上线的第一个动作,肯定是将代码合并到线上,但在合代码之前,需要经过部门内同学的cr,cr有如下几个作用,1,提前发现bug,bug有两种,一种是实现上的技术bug,一种是对需求没有吃透的流程bug,但是无论哪种bug,通过cr,内部同学都极有可能提供帮助把问题发现并解决;2,统一代码规范,一个服务可能会有好多同事同时参与开发,这时,一个良好的代码规范就很重要了,而代码规范的保持,尤其是对于新接触服务的成员来讲,就成为了挑战,这时候cr代码可以提供一个机会,让其他成员把新成员的代码风格给统一起来;总之一次代码cr,就是一次头脑风暴,这样只会让我们的代码越来越好。
回滚方案
经过了若干前置步骤后,如果线上代码还是有问题,那就不得不回滚代码了,而传统的回滚方案,就是借助平台工具,将部署的代码完全回滚到上一版本,快速解决问题。但是有的时候,这种快速解决问题的方案,却并不见得那么快速,回滚一套部署,往往需要几分钟甚至十几分钟的时间,回滚时间多快,就意味着线上越少损失服务能力,所以,除了依赖平台本身,我们还应该想一下自己能做些什么,举个例子,当我们修改部分逻辑时,可以提前设置一个开关,默认使用新逻辑,打开则使用原有逻辑,这样在上线初期,如果确实因为新逻辑不够健壮导致bug出现,则可以通过开关转换,瞬时更改逻辑,使服务对用户的提供能力更稳定。
灰度阶段
上线操作,灰度阶段是不可省的,灰度是指上线操作先进行一个小范围的尝试工作,然后再慢慢放量,直到这个全新的功能覆盖到所有的系统用户,也就是说在新功能上线的黑白之间有一个灰,所以这种方法也通常被称为灰度。灰度是一种过渡,如果新版本有问题,这样不至于影响到所有用户,而线上监控却能够及时发现问题,快速回滚,避免问题扩大化,所以,灰度阶段,作为rd,我们更要小心谨慎,灰度阶段要适当长一些,比如一个小时到半天时间,尽可能让所有问题在此阶段暴露出来,让我们更从容处理问题。
全量阶段
在这个阶段,还是要注意监控各个指标,虽然经过灰度的验证,bug出现的概率比较低了,但是我们依然要谨慎,因为魔鬼处于细节之中,我们并没有完全把握我们的代码会在什么时候出现问题。
上线后
上线后,我们需要一些必要的操作作为依据,证明上线的代码是没问题的。第一是接口调用测试,有的时候,测试环境的接口没有问题不代表线上的也没有问题,所以我们必须自己亲自调用一下去验证,毕竟眼见才为实;第二是持续观察监控,既要观察服务的整体服务能力有无下降,也要观察服务的各项基本指标比如内存,线程数等有无异常,因为许多时候,这种问题的出现并不是那么及时的反应在报警上,需要我们细心观察;第三则是注意回滚,当我们观察监控或发现接口调用确实有问题的时候,我们要时刻注意回滚,甚至当我们没有发现任何异常,但是当问题大面积反馈的时间和我们上线时间高度重合的时候,我们也要及时进行代码回滚,因为我们在更新业务逻辑的时候,一些隐藏的关联问题我们是很难察觉到的,因此及时回滚尤为重要,以至于公司内部将代码回滚作为解决问题的第一标准操作。
【论对上线存敬畏之心】综上,在服务上线的每一个阶段,我们都应该怀着敬畏之心,如履薄冰之念,一颗红心,两手准备,时刻要自信的写着自己的代码,也同时要谨慎的为自己可能造成的损失去设计补偿方案,如此,也许方案并不完美,但是怀着一颗敬畏之心,你肯定不会走错。毕竟心存敬畏,才能行有所止。

    推荐阅读