[关闭]
@gaoxiaoyunwei2017 2018-01-07T04:43:21.000000Z 字数 23045 阅读 498

神聊《DevOps HandBook》 Part IV:工作方法第二步 反馈实践

大熊


导言

很高兴参与DevOps时代社区的拆书联盟第一季活动,有幸能与几位DevOps大牛一起解读《DevOps Handbook》一书,这本书作者牛,内容也很牛,就连著名的培训机构把这本书作为DevOps认证培训教材。书中不仅方法论和实践丰富,而且所有案例都是取自于硅谷互联网企业的DevOps最佳实践,很值得我们研读。《DevOps Handbook》的拆书活动,共分成七部分,我负责的内容是“DevOps三步工作法”的第二部分:反馈实践。

《DevOps Handbook》把持续反馈的内容分成三部分:
* 第一是持续反馈的技术与案例,介绍在持续交付之后构建持续反馈体系的方法,主要是监控和告警能力的建设。
* 第二部分会介绍优秀的持续反馈如何反作用于持续交付和持续集成。
* 第三部分介绍实现持续反馈的非技术要素,包括组织、人员等软文化。

第一部分介绍的是持续反馈最核心的技术——遥测技术。

1.持续反馈的技术与案例

1.1认识遥感技术


我是做运维出身的,我们聊到监控的话题,这张图是比较经典的图,如果没有很好的规划我们企业运维对象监控的能力,往往我们发布完之后都是一脸蒙圈,保障业务质量要靠求神保佑。同时做运维监控的成绩很难被衡量,而企业对运维监控的期望值很高,这便有了这么一句话:“出了任何故障,其他环境都是可能有问题,唯独监控是一定有问题!” 如果监控发现不了问题,那一定是监控做得不到位。你很难说服老板说你花个几百万或者十人的团队去把这个监控系统做好,给企业或组织带来什么样的价值,我们怎么样去说服老板,怎么样体现运维的价值,而不是让运维一直在DevOps价值流的最下游,这是我们这次拆书会要探讨的一个话题。我会摘取很多《DevOps Handbook》中硅谷实践的案例,也会结合我在腾讯这么多年的技术实践,也会拿腾讯的案例跟大家共同探讨怎么做好运维监控。

这本书把持续反馈里面核心的技术用英文描述Telemetry monitoring,翻译成中文是遥测技术。当我念完正本书之后,发现这个遥测技术就是我们平常所说的监控和告警。本书分了四个大的部分去阐述,第一部分是指标,提出了我们在做DevOps的过程,无论是持续集成、持续交付还是业务已经投产运营了,我们要监控的指标有哪些,这里包括了我们要识别出有哪些指标应该纳入我们的监控范围,我们要怎么样去定义它,怎么样描述这个指标,举个QQ业务的案例,作为运维我们要怎么样描述QQ这个业务是健康的。按我们正在执行的经验,我们会把QQ的在线用户数C2C的消息量,还有发图片、信息,这种量作为度量QQ健康与否的标志,就是我们对不同指标的定义。

还有范围,像QQ这么大的平台,我们要看一万个指标来判断它是正常的,还是说有一个指标就可以定义它是不是正常的,这就是我们对指标的一些讨论,后面会具体深入讲。第二个是能力,为了拿到这些指标去度量业务质量,运维人员要去处理它,要对指标按照服务器集群或业务管理的方法、管理策略,来进行指标采集、分析、异常识别、通知等。这些能力会依托于监控平台,为IT技术人员甚至是为业务产品人员提供服务。换而言之,如果要实现一个监控平台,从基础设施选型、存储架构设计,到软件与硬件的需求,再到一些非功能规范,像日志标准化等这样一些能力,会在探讨持续反馈的遥测技术时跟大家聊到。

为什么要遥测技术,先跟大家分享一个笑话,有时候运维同行交流时都会讲一个段子,其实运维挺容易当的,只要懂的运维三板斧:“重试,重启,重装!”,就行了。当然这只是一个玩笑,笑话之余还是想引出一个很现实的问题,运维人员日常在处理异常问题或故障时,经常会走入一些惯性思维的陷阱,书中提到一个案例,有多少人在使用Windows系统的时候遇到蓝屏,用户可能本能的会去重启Windows操作系统,慢慢你觉得Windows的蓝屏习以为常了,而重启windows便成为条件反射的解决方法。

但是DevOps的方法论里面其实是不建议或者要人们去杜绝这种惯性思维的陷阱,遇到这种问题应该反思一下,究竟为什么没办法通过监控来识别这个问题,定义的监控指标是不是没有覆盖到这个故障的发生,如果要去度量业务的质量,那指标必须要覆盖它。不要认为这个事情我们看不见,它就是不存在的,运维最怕的就是墨菲定律,你越不想它发生,它就越有可能发生,如果运维发布了一个应用程序,但是对它的监控仅仅只停留在对服务器的CPU、内存、网络、硬盘的监控,对它的业务指标视而不见,无论那些硬件的指标运行的再好,有可能它的服务都是有问题的。所以我们必须先弄清楚运维的对象应该怎么样去制定我们覆盖的指标,去度量它。


书中提到了Etsy公司的监控实践,简单介绍一下Etsy公司,这本书的作者是三步工作法公司的CTO,Etsy公司是做垂直电商卖一些小众的手工艺品。Etsy在公司的监控实践里,它2009年就开始从传统的运维模式向DevOps转型,到2011年,这本书的作者认为Etsy这个公司已经转型的差不多了,是一个比较成熟的DevOps公司。当时他们为了针对一个很简单的电商系统,所有应用层面的指标已经超过20万个,覆盖了他们的应用、操作系统、数据库、网络、服务器、安全等等所有的对象,他们的技术实现是用ganglia做数据采集,用现在很流行的grafana做监控大屏。

书中特别提到一点,2014年时Etsy公司的监控指标已经突破了80万个,但是他在这80万个监控指标的基础上提炼了30个指标来作为他们的大屏监控,无论他的指标再多,他们只要保证这30个大屏的指标不异常,他认为全局的服务是ok的,这个跟腾讯的海量业务运营下我们的监控实践得出的结论是一样的,目前腾讯SNG有超过10万台的服务器,业务指标加起来绝对是Etsy公司的好几倍甚至上十倍,我们也得出了一个这样的实践问题,在分布式架构、微服务架构、业务高可用、容灾等技术加持下,度量业务的质量是不是还需要去看到每一个最细节的指标,还是可以再高度提炼一层用来快速度量业务质量的指标?这时候我们的运维团队选择了提炼了指标,在腾讯内部的DLP智能监控平台,会从成千上万的指标中提炼业务生死指标,用来代表该业务的关键质量。并且针对不同的监控场景,如异地多活架构的监控,还抽象了专门用于调度指标的监控,这些都是为了把监控指标更好的分层,让运维在服务出问题的时候能快速发现,能及时响应处理这个故障。

书中有个观点,如果想评判一个企业的监控能力的好坏,可以参考下图(左边),是DevOps报告对2014年硅谷很多家公司统计出来的,这张图的数据认为监控能力做得好的企业,它的工程效率会很高。同时,统计数据中认为运维处理故障的能力是监控能力弱的168倍的。MTTR代表故障发生之后修复故障需要的时间,MTTR时间越短,监控能力越好。右边这张图,MTTR等于MTTI,就是发现故障的效率,还有MTTK,找到这个故障根本原因的一个平均的耗时,然后到MTTF、MTTR。所以我们有理由认为只要把我们的监控能力覆盖度做上去,我们可以更快的缩短MTTR,让我们的业务质量可以有更强的监控能力去保障。
image.png-117.2kB

构建遥测技术的基础设施,书中提到一点,传统IT团队,如果要做监控,举一个案例,现在我们很多传统行业,以金融为例,金融行业它的组织架构先天分了研发中心、测试中心、数据中心,数据中心更多的是运维,他们负责了基础设施、数据库维护的工作。对于数据中心来说,如果按照传统职能划分,更多的是保证基础设施指标的可靠,基础设施传统意义上就是网络、设备、主机,更多一点事故,有没有慢查询等。还是套用刚刚那句话,在业务高可用或者分布式做了这么多年的背景下,我们监控这些指标是不是足够,这些指标是不是能直观反馈出业务真实的情况。显然答案是不足够的,为此本书提出了下面的能力,需要体系化的去规划监控平台的能力,这里包括了分层监控应该怎么样做,包括对不同的架构层级,IaaS层应该监控到什么能力,PaaS监控到什么能力,应用层监控到什么能力。还有数据处理能力,它是不是能够满足维护业务高可用、业务可靠质量的要求。
image.png-103.9kB

腾讯运维的思路也是类似,如果一个典型的互联网架构按照下图展开,DevOps所提倡的价值流,它是从右往左去给用户提供服务,怎么样产生价值,从左往右,用户使用了具体的服务,才会对企业产生价值,我们的技术也才能发挥原有的要实现用户需求的目标。

我们做监控也是一样,按照这样的层级划分,在腾讯织云的监控平台里,对所有的监控指标进行了这样的分层管理,我们把最基础的更贴近于基础设施,没有带任何业务属性的、具有很强的通用性的指标叫低层次指标,把跟业务贴近的指标称之为高层次指标。但是在海量运维的压力下,就像我所在的腾讯SNG社交网络事业群,所有超过千万的用户的业务有160多款,这么多款业务我们没办法说每个业务又这么复杂的微服务架构,我看你高层次指标,度量你可用性,还是看不过来,因为我们的运营部只有100人,100人维护10万多台机器,160多个业务,假设每个业务有5万个指标,那共有多少个指标?所以我们在高层次指标之上再提炼一层,刚刚也介绍过的DLP指标。对应看这个倒三角形右边的图,我们基于不同的指标监控,还针对性的去提炼了一些运维的工具,这些都落实到织云的产品中,为的是帮运维更好的去处理不同层次的指标。

image.png-38.2kB

举一个例子说明上图,针对低层次的指标,假设应用程序的进程不存在了,那意味着应用程序进程挂了,端口也会不存在,究竟监控系统应该告警还是可以通过自动化的方法去把它解决,还有主机的硬盘容量满了,是不是有一些约定俗成的规则去自动化的完成无用文件的清理,实现简单的治愈。同样的,高层次的指标有很多,像我们做业务监控时,究竟应用的日志是落地还是不落地,如果是落地的,就通过日志去采,变更的过程与业务指标变化之间关联如何实现,配置管理要怎么做,怎么样通过高层次指标提炼出DLP指标,这要求CMDB、自动化系统、监控系统之间要有关联的方法和经验沉淀。

1.2遥测技术的应用


介绍完遥测技术,再来看看在它的应用场景。遥测技术可以应用在什么地方,书中给了三个方面。第一,对运营中的服务,已经投产的业务应用,我们应该有所监控、有所识别。第二,对CI/CD阶段,同样也要提炼一些指标来进行识别,例如每一次构建耗的时间、错误数或失败数,也需要去做监控做统计,部署的过程中,有哪些测试环节出错了,这个发布是不是应该正常把风险带到生产环境,还是说发布的一个过程。第三,书中还提到在构建监控能力时,应该尽可能把监控能力服务化,包括哪些能力是可以给用户自助去完成的,或者提供可二次开发的API给开发团队,让他们按照他们的使用场景去封装。还有监控平台自身的高可用和性能的评估,这是很DevOps的做法,我们一起来看怎么样去达到这一点。


腾讯的一个案例,我们对基础设施的监控不仅仅局限于一些简单的硬件指标,还把它深入拓展成很多维度的指标,这张图不一定枚举全,但是想说明这样一个事情。为了保证不同环境的一致性,我们甚至会对内核参数的配置、NTP时间服务、系统重要的补丁,crontab的内容,都加上监控。同样,对硬件产生的dmesg、coredump、操作历史、负载等等的监控,都把它归为系统监控,系统监控在腾讯的实践中是属于最低层次的指标,这些低层次指标可以逐层汇总成高层次指标,能够反映业务的一些问题。

如果低层次指标要往高层次指标去靠,最直接做法,相对也是不需要研发团队太多去改动他们的业务代码或者说不需要嵌入太多运维团队要求业务逻辑,《DevOps Handbook》这里提出,可以通过对应用日志的监控来实现对高层次指标的收集。书中的例子,美国航天局NASA,每次发射火箭时,工程师们都会做足了指标的采集,对每一个零配件的方方面面具体在运行时的表现都有实时的监控,来确保这次火箭发射。因为一个火箭发射可能涉及几十亿上百亿的成本,如果发射失败,这个消耗是很大的。在模拟操作时,就应该确保每个零件是ok的,以保证结果是符合预期的。这里提出来,在DevOps所提倡的IT价值流的过程中,每个成员在价值流中的每个动作是不是都覆盖了,指标监控都有相应的日志输出。这里对日志提出了几个方面、几个维度标准化管理的思路,包括对日志的类型应该怎么样做,包括记录业务流水的日志还有技术的日志等,甚至可以记录它的性能信息,记录它事务的一些信息。

日志需要分成不同级别,与Linux系统的syslog日志级别类似,包含Debug、Info、Warn、Error、Fatal的级别,不同的级别意味着输出的详细情况是不一样的,这就让日志监控拥有分层,或者监控识别异常的时候,它就会有一个取舍,知道哪一个错误是优先级的,例如像Fatal的错误,致命的错误,可能我们在设计一个告警能力的时候,它就应该打电话,如果只是警告的级别,可能隔天发一个统计的邮件让我们去处理。还有对日志格式的要求,建议我们从日志输出的路径、内容,它的格式是什么样子的,它的编码是什么样子的,是用逗号分割还是用分号分割还是用井号分割等等,都是便于我们在做日志分析的时候采集难易度的问题,还有日志管理的问题,日志怎么写的,是无限的这么写下去单个文件还是每个文件写200兆,循环写10个文件,这些都是需要我们在做日志监控时要考虑清楚和提前规划的。


此外,在定义日志内容的时候,书中还给了一些建议,我们可以按照指标类型的不同,可以区分开业务逻辑的日志长成什么样,非功能的日志长成什么样,性能的日志,还有可以尽量去记录一些日志的关键事件是怎么样的,这是书中给的几点建议。右边是腾讯运维在做项目时的一些日志标准化的图,为了脱敏,我画掉了一些关键的信息。大概想表达一点,如果运维团队能跟开发团队有一个很好的协商,在真正编码之前我们能把很多可能对业务逻辑、功能逻辑无关的一些非功能的需求说明清楚,提出来之后,实现这种东西,对大家都是有好处的。在持续反馈的阶段,这个很有利于运维对服务的监控。


做织云平台日志监控时,我们对日志监控能力做了从低到高的分层,最简单的日志分析,在织云里叫做特性上报,做监控平台的工程师不需要去理解业务的日志是怎么样计算的,各个指标之间究竟是做加法、做减法还是做最大值、最小值、平均值这种逻辑。监控只提供平台能力,而业务开发或运维只要在应用程序中或在旁路的脚本计算好,然后将得出的值,通过调用监控平台的能力往服务端去上报。织云监控agent会暴露上报数据的API给用户,用户自定义的算好逻辑,然后给监控服务端上报数值,例如100、100、100、120、150、160、170,然后服务端就会根据用户配置的异常识别策略,假设大于150我就会给你发告警。这就是一个最简单的方法,这个是解耦的比较彻底,但是这样要求研发人员他可能要具备比较强的意识,这种特性上报的方法会在开发侧造成比较多的工作量。

还有一种这种的方法是日志采集,我们按照约定俗成的日志格式,应用程序把日志输出,运维按照标准化约定的格式去做日志的监控,识别完会在服务端展现,这个技术类似于开源的ELK技术。最好的状态是日志不落地,直接通过API的形式,应用程序直接把它的流的数据上报上来。这种监控方法要求研发要键入一定的运维提供的API、SDK,提供统一的数据传输通道的能力还有汇总的能力,例如要做一分钟的汇总,来降低Agent端对服务端的压力,这一块特别是在移动APP的监控,像QQ同时在线有2.7、2.8亿,如果不做收敛,每秒都上报,会有几个问题。第一,用户端的耗电承受不起,第二,服务端要囤大量机器来扛住这么大的并发上报请求。在腾讯的监控实践中,基本上90%以上都是通过嵌入API、SDK形式实现对业务的监控,因为这样做不仅实时性好,而且在客户端这边为了做监控而消耗本地的硬件性能也是相对最可控的。


再附上腾讯的流式监控平台的架构,无论是对日志文本的采集还是对流式数据不落地的数据监控模式,对服务端的能力来说都是类似的,如果大家做过流式监控,看这个架构图都大同小异,流式监控无非分成三个部分定义,第一部分是数据采集端,第二部分是列的处理逻辑端,第三部分是做最后的告警还有一些数据可视化的端,这一块不详细讲,在腾讯做了这么多年的监控实践里,最难的是我们如何能够通过这种流出来的后台架构,能够承受海量的流式数据的上报。

我在《运维三十六计》里也提到了容量管理的原则,空间换时间,我们在实时处理的Storm集群之前搭了消息队列,让消息队列来扛住这个大并发,在消息队列之前还搭了一个做转发请求的集群。这个集群可以做几个用途,第一可以按照我们的需求将不同的流数据转发在不同的Storm集群去处理,来分摊大业务上报请求量,避免因影响其他的小业务。Storm处理完,我们会把准实时的结果数据存在消息队列kafka,在线的一些运维监控系统就实时,因为kafka跑的是内存,可能成本比较大,这个取决于投入监控的运营成本,成本投入得多,那存储的时长越久。


《DevOps Handbook》还提到怎么把遥测技术服务化这里协调提到一个Etsy公司的案例,Etsy公司的这个工具叫statD,它在github那里已经开源了,我专门去搜了一下,有1000多个星,大家如果感兴趣也可以看一下。这个技术跟我刚刚介绍的织云特性监控的技术基本上一模一样,它其实就提供了一个Agent,让你可以部署在具体的主机上,它不理解你的业务逻辑,你自己的应用程序要按照statD的格式,把监控数据处理成K:V的形式,例如CPU50、CPU51、CPU55,这样去报,它就会在后台绘出右边这个图,你上报K是Login100、Login200、Login50、Login30,你就可以在它的服务端设置一个最大、最小值,然后它来做告警。

当然设置阈值是不是最优雅的,我们会探讨怎么样去识别异常。具体statD怎么样去实现这种方法,我没有细看,我们可以基于我们做织云特性监控的实践经验去跟大家说,必要的四步,首先申请id,去给这个id报很多K:V,或者报字符串,报字符串也是可以做告警的。你的业务程序一直去自我判断你去上报,ok,你突然报一个no,然后你在我的服务端配置,遇到这过no的字符串的时候就发告警,或者你报Error、Fatal都可以,或者你也可以设置成所有非ok的都会发告警,然后服务端就会给你绘出来,ok就一条线,非ok就掉下去了,告诉你策略的识别,这个比较好理解。


书中还提到假设我们现在已经构建成了一套很完善的遥测技术,监控告警能力做得很好了,它还提出我们光是有指标还不行,我们还要把这个指标在DevOps团队中透明起来,因为DevOps文化里有一个很重要的文化就是要分享,我们之间没什么可以隐瞒的,各角色成员之间的信息都是透明的,开发人员不要捂着掖着,你代码质量差就是差,你要告诉团队。运维也是,发生了故障,你就告诉团队错了。书中还提到一点,当然老外的文化肯定是强调要免责、不问责、不罚款,这是贯彻实施DevOps的价值观。但是还提到一点,有点惊呆了我,我告诉我的小伙伴,我的小伙伴也惊呆了。书中特别提到一点,在Etsy的文化里,他们会把自己的故障信息甚至都同步给他的客户,他的大屏会对客户开放,并且上面发生的每一个故障客户都可以看得到,Etsy工程技术的负责人说,把监控指标具体的情况对整个团队公开,不仅有助于公司内部IT团队的团结,加强他们的沟通、信息的传递、持续的反馈,公开给客户还有利于增强客户对他们技术能力的信心,但是不确定在中国这样操作合不合适。


书中还提到,我们要不停的去思考为什么遥测技术能给我们带来怎么样的能力,像我们之前也提到了,做好了监控体系的规划和它的指标覆盖,可以把生产环境中的MTTR,就是故障处理的时间缩得很短。同时对生产质量做很精确的度量,在做持续交付的时候很好的度量。同时,当故障发生的时候,这个指标很清晰,是谁的问题,就事论事的去解决它,而不是单纯说开发团队把锅甩给运维团队,或者运维团队为了不想背锅又去扯皮,加重上线发布的流程等等,这种东西都是不利于DevOps提倡的最终实现企业的共同目标,因为企业IT的目标就是为了实现企业的目标。通过这样的做法,我们能够不停的去修复指标,不停让我们的开发和运维、测试合作更紧密,慢慢就变成DevOps的团队。


书中还提到一个Linkedin监控平台的实践,Linkedin是2003年成立的,当时他那种业务模式在北美很受欢迎,迅速获得了用户,用户的基数应该是独角兽式的增长,一年增长到上亿用户。他们很快意识到一个问题,当年运维团队做监控的时候也只是针对传统基础设施的监控,他们当时起了一个实习生的项目,让实习生尝试去推一些日志标准化,自己写一些采集的方法,在基础监控之上做好业务监控。

这个案例最终得出了一个平台,叫做Zenoss,这样一个Linkedin现在在用的系统,他现在也把这个系统产品化了,大家也可以在谷歌上搜一下,这个系统也可以对外提供服务,监控你公有云上云主机的服务,可以上报到Zenoss的服务端,可以给你做可视化的监控,这是当年一个实习生做的项目,截止到2010年时,它已经变成Linkedin这家公司里最核心的监控平台之一,由这个监控平台所衍生出的很多核心的业务指标都被用大屏展现出来,所有去Linkedin参观的客户也好,自己内部的无论是业务人员还是IT人员,都可以看到,是很关键的东西。作者也希望从这个案例论述监控真的很重要,但是我们的监控不仅仅是为了做监控而监控,一定要去思考怎么样能跟业务的价值做贴合,这才是我们做监控的意义。


除此之外,有了对指标的定义,还需要对监控的指标做持续优化的工作,包括我们一定要坚持找到我们目前所有的指标是不是有一些缺陷,例如不要陷入这种惯性思维,假设有一个指标,它一直告警,久而久之就像狼来了不管它了,我们要重视每一个误告警,要要让它根治。这里我特别想提一个,我2009年在腾讯负责的是系统运维,当时我们生产环境的服务器规模还不是特别大,2万台实体机,一个系统运维,就是我。当时老板给我安排了一个特别的任务,老板觉得说为什么生产环境的硬盘容量告警一直困扰着大家,要求我想办法去把它优化掉。当时我做了一些数据的分析(95%的硬盘使用率就告警),发现一些硬盘告警重复告警很多,每次告警完,虽然有人及时处理,但仅处理到90%,并未根治。可能隔两天又写到95%,又产生告警。按照二八原则,80%的告警都集中在那20%的机器,没办法可以根治它。后面我在我们内部推磁盘清理策略,把容易产生告警的自动清理的规则,人能清理,机器也可以清理,把一些日志不合理的情况修复了,这个告警就不存在了。这个案例也是想说明我们千万不要陷入这种惯性思维,不要让狼来了长期存在下去,我们要让误告警消失。

文章还提到间指标上下文关联很重要,例如我在社区在同行里也经常交流这样一个事情,很多运维同行都提到了一个问题,我在做变更的时候,监控系统太多了,我没法每个系统都去屏蔽告警,我不屏蔽,做变更时又会产生大量的误告警,怎么办,这个典型就是一个监控指标没法跟其他系统进行上下文关联的分析。我在做织云产品设计时也考虑了很多,我们的变更怎么样跟我们的监控,我们的基础监控怎么跟我们的业务监控去关联,一定要有个上下文关联的机制,无论是通过配置还是通过自动去识别,这个关联是很必要的,特别是在我们海量规模运营的过程中,一定要做好。同时他还提出需要对我们持续交付的全过程来进行监控,这里给了个建议,他认为持续交付的全过程主要分成五大块,第一块,我们部署完,你能不能马上看到我业务指标的变化,你部署完能不能马上看到我具体部署的这个应用程序或者说这个微服务它的延时、负载、返回码、成功失败率的变化,还有我部署完这10台基础设施、10台主机,它的基础信息有没有变化,硬盘使用率有没有涨,硬盘IO有没有涨,等等,这个供大家去完善。


我们有理由认为指标监控的目标绝对不是为了监控这堆废铁它是好是坏,最主要的目标还是要监控我们的业务,这个铁盒子,我在外企呆过,外企把主机和服务器叫box,这个box运行的状况其实不是我们最care的,我们care的是假设运维发布了100台主机,哪怕有10台失败,如果业务不受影响,相应采取的处理措施是完全不一样的。这样我还是引入刚刚那个图,低层次指标其实是面向于技术人员的,或者说低层次指标我们面向于运维,那运维有必要去标准化它,通过一些高效可靠甚至是自动化的方法去解决低层次指标发现的问题。你通过负载均衡,通过怎么样的一些运维工具去处理。高层次指标是要运维与业务开发一起去看的,最终能代表业务质量的指标,如果拿腾讯织云的实践按理来说,就是DLP指标,技术人员(开发与运维)应该是跟业务共同去看的,如果这次发布,在灰度的过程中业务的DLP指标就受影响了,那这个灰度必须马上停止回滚。越面向于技术的指标越丰富,越面向于业务越是要少而精的,这样才能体现出监控对业务的价值,还有技术驱动业务价值。


这里是书中Etsy公司的案例,在他们部署Pipeline中,部署Pipeline就是他们自动化部署的流水,大家其实可以看一下,黑色的竖线是他们在做PHP发布的时候,他们一发布,7点发布,发布完陆续就会有一些深蓝色的新产生的bug,有用户反馈了,浅蓝色是他们逐渐接到很多反馈,8点他们再发了一次变更,修复了深蓝色的。然后去做这样的一个变更跟我们监控的结合。


除了刚刚介绍到的几个层次,我们要对基础设施低层次的指标要监控,高层次指标要监控,DLP指标要做监控之外,在《DevOps Handbook》里还提出了,对指标的覆盖度不要满足于现状,要确保每一个会影响到DevOps交付流水线的所有对象相关的指标都要纳入监控。这里也给了几点,基础设施对一些环境变量是不是也可以监控起来,资源的一致性,现在我们做很多自动化的操作,就存了两份数据,一份是在数据库的数据,一份是运行在生产环境的数据,怎么样对比它的一致性。今天我们没有重点去聊自动化,如果后面我们有机会直播聊自动化,我也可以跟大家聊一下我在这块的技术实践是怎么实践的。还有日常运维活动,像有些团队经常在凌晨做的跑批量操作,每次跑批的效果是怎么样的,是不是每天它的耗时都是差不多的,是不是突然有一天,假如跑批平常都是用一小时的,今天十分钟就跑完了,有可能就是异常, 运维对这些活动都需要去监控,还有备份、调度,甚至是舆情,甚至是看看App Store有没有人在骂业务等等,这些监控都是需要不同的指标去覆盖。

讲完监控技术、监控基础设施还有监控指标应该怎么样定义怎么样去规范,接着聊一下第一大部分的第三小部分,拿了这么多指标,怎么样可以识别每个指标是正常还是异常,一些异常分析算法。


书中给了一个案例,Netflix,美国最大的视频网站,当时Netflix遇到的一个问题,因为做点播的视频平台,他们的集群很大,大到一些集群有大于1000台主机,他对这1000台主机进行监控的时候,他们遇到了一个问题,原则上1000台机器提供相同的服务,它所有的指标表现都是一模一样的,他们遇到的第一个问题,怎么样可以找到一些outlier,用中文解释就是一些离群值,怎么样识别。他们可以结合他们的自动化,假设1000台机器,所有的cpu都是50%的负载,突然有10台是80%,又是无状态的,我是不是可以自动把那10台干掉,把80%弄掉,因为基于木桶原理,这里也广告一下,在《运维三十六计》的容量管理里也写过类似的策略,对所有的容量管理,一个集群都是一个木桶,木桶的最短板就是你这个集群里负载最高的设备,你就把它干掉,来确保水位一样,这样才是最健康的集群状态。


Netflix找到了一个方法,下面我们看一下这个方法,指标异常分析的第一种方法,标准差。这个方法其实就是反馈一个数据集它的离散程度的,标准差越小,这个数据集里面各个值之间偏差越小,反之亦然,偏差大,越离散就有问题了。标准差用了一个算法,叫高斯分布,高斯分布是高斯发明的,在腾讯内部我们习惯用正态分布这个称呼,分三个级别,右边这个图,凡是符合标准差分布的数据集其实都是处于一个中型的分布,当我们第三标准差偏差越小,数据和数据之间的差异不会超过99.7%。这里我列举了它的一些优点,不具体展开讲这个算法。标准差的优点有一个好处,不需要人工定义阈值,在多年织云监控实践中,得出了一个经验,阈值是不可靠的,随着业务量的变化或者随着服务的升级,阈值的准确性要靠人维护,一旦你照顾不周,就会变成误告警,然后整个监控告警可信度就会受到挑战。所以我强烈推荐大家能不用阈值的就不要依赖阈值。用正态分布实现动态阀值的不足是对数据集有一定的要求,你必须要符合高斯分布中型的图形才可以。


标准差的识别,它给了一个案例,当有一个Nginx作为web服务的时候,假设突然502的返回码增加了,出告警了,就以HTTP的返回码作为业务质量的反馈,我们马上就可以来看每个监控对象指标的表现情况,应用层面是不是被攻击了,数据库被拉挂了,后端服务不可用,或者操作系统级别是不是有什么问题,是不是这时候在做一些数据大量的备份,把主机的IO吞吐满了,导致DB数据处理性能很差,有一些SQL堵住了,网络吞吐是不是受影响了,这样技术人员马上就可以通过标准差的方法去识别,因为一台Nginx,当业务请求固定的前提下,在用户不会爆发增长的前提下,所有的业务指标其实都是一个平滑增长的过程,如果按照我们第二标准差,你前一个点和后一个点的数据不要超过95%,前一个点还是100%,那你后一个点是95%,我都认为你是正常的,你不要跌到90%或者80%,这样我们就可以结合业务场景说这种场景可以结合第二标准差,动态的判别识别出异常。如果企业的业务更稳定,就像腾讯很多业务相对都比较稳定,就像QQ的同时在线,是很稳定的,我们就可以用第三标准差来做这种识别。


标准差很好,正态分布很好,不需要设置阈值,很自动化很智能,但是它对数据集有要求,假设现在有一个数据集是像左边这个图形这样,不满足高斯分布,我们应该怎么样去处理。大家可以看左边的图,如果按照高斯分布的方法,把每个时间点的平均值都求出来,然后你会发现它的图形像右边这个图形一样,数据集不符合高斯分布的图形,不是中型的。它是一个长尾形状的,这种形状没办法用正态分布,因为如果用正态分布用第三标准差,你会发现就会一直告警,用第二标准差、第三标准差,第三标准差都不行,你看它9月9号那个值,跌得这么高,是不行的。但是事实上又会存在这种图形,是什么样的情况下会存在这种图形,就像广告投放,它是有一定的规律性的,例如每天都会投一些新广告,举业务场景,微信广告,但是有些广告点的人多,有些点的人少,点的多的可能就比上一个广告高一点,但是也不会高到哪里去。一旦高起来,运维又要做一些动作,例如可能需要扩容等,这种方法怎么解决。


书中给了另一种方法,与腾讯监控的实践类似,书中把这种告警异常的识别方法给了一个名字,叫平滑性或者平滑度,它其实是一种很典型的做法,我们在互联网做监控的时候也会这么做,那就是基于时间序列的指标的分析。平滑性,右边这个图,蓝色的线代表了实际业务的情况,黑色的线是我们取了5分钟一个时间窗口,或者3分钟、1分钟一个时间窗口,把这个时间窗口里面实际产生的数据做一个平均,这个平均的目标是为了削峰填谷,就是抖动的全部把它过滤掉,这样得出来的一个平均数的曲线是一个平滑的值,对这个平滑的值再来用标准差,再来用正态分布,再来用跟历史数据的对比,反正就不用阈值,你可以跟同比、环比对比,这个数值如果是平滑的,如果它没有超过标准差,那认为这个数据平滑的,它是可以正常运作的。


书中还给了Netflix的案例,Netflix有一个工具,大家都知道Netflix是亚马逊云最大的客户,他全部的服务都是跑在公有云的。他们需要根据他们具体的一些广告、电视连续剧,收看得好,那他的广告曝光率就高,他需要根据他的动态负载来自动扩缩容,这个场景其实在腾讯或者在我所负责的织云平是很常见的场景,容量涨了,马上给它扩容,下下去。左边这个图其实就是基于时间序列它的业务走势,基于这一个时间序列的走势,我们可以预测未来一段时间业务走势是什么样子,或者根据历史经验,如果我的曲线涨成这样,它肯定就涨不上去。这时候就可以启动他的Scryer,申请AWS的机器给他扩容。右边这个图,下降的时候都是垂直下降的,这就是它的容量,它的容量如果是70%,扩10台机器可能变成65%,就垂直下来了,然后再扩,一点点这样扩下去,而不是一次扩到位,他是根据最真实的容量表现情况去扩,保证他每一笔消化在公有云上的费用都是性价比最高的,而不是说我现在的业务涨上去了,老板你马上给1000台机器给我储备,但是它是不是涨到1000台的请求量,不知道,所以这时候这个做法值得我们参考。这个做法跟我在一些运维大会上分享腾讯织云的做法也是类似的。


书中还提到了一些针对异常指标分析的方法,包括包括傅立叶、K-S,K-S是基于历史数据,可能运用了统计学同比环比这种东西。还特别提到,无论是Etsy公司还是Linkedin公司,他们认为监控的平台做到最后,他们都在运维团队培养了一些叫做学统计学的运维工程师,这个我们也一样,甚至现在我们在做智能化监控的时候,我们织云团队也招聘了一些学数学的博士在给我们做机器学习智能算法,也希望后面跟大家深入探讨。书中提到的是方法无限,但是我们为了更智能的去预测或者分析指标的异常,我们没办法逃避的,必然要面对运维人员或者做监控平的运营开发人员,他必须得掌握一些统计学或者一些机器学习的新时代的高科技的算法。


这里给了一个Etsy的案例,像这样的一个曲线分布,如果用标准差的方法或者说平滑度的方法,都解决不了这种问题。这个图形如果基于平滑度的算法,一旦它的业务量跌下来之后,在12月,在这里,业务量跌下来之后,在这里如果是平滑度的话,它会告警一次,但是告警完,如果你没及时处理,后面它的平滑度就不会再告警,因为它一直会很平滑,因为它的指标没有恢复到之前的那个层面。


对于这种图形,他提出了可以基于KS算法,基于历史数据,在这个虚线的时间点,一定要恢复到这个值,不然它就没办法。书中海油一个观点,我们做业务监控时,一定要严格意义的根据我们的业务形态去做。假设这个图形是我们电商做完促销回归到平常,那是ok的,但是我们做促销,像马上双十一,双十一一定会涨的,明年的双十一也是会涨的,后年的双十一也是会涨的,如果有一年的双十一没涨,那它一定是有问题的,这些历史数据我们都需要不断去沉淀,应用到我们的异常识别中,让我们的算法更加智能。提一下机器学习,机器学习有一个好处,无论是有监督还是半监督的算法,可以通过一个算法库,它可以按照一些比较智能的方法,能够选用一个最精准的算法来分析现在的图形,找到异常。

2.让发布更可靠&安全

2.1部署pipeline中的监控

持续反馈的技术,聊一下怎么在Pipeline中部署监控,开展监控,在Pipeline中应该监控什么东西。

讲一个案例,Right Media是一个在线广告的公司,他们的广告库存是动态的,一旦有客户需求,他就马上要扩容,客户说我要投一个广告,要上线一个游戏,这个游戏会有很多人来玩,他就马上要扩容。这时候遇到一个问题,运维人员部署很慢,开发人员甚至嘲笑运维人员,说你们连最本质的工作都做不好,你们为什么会害怕部署。当他们CTO把这个职责放给开发团队的时候,开发团队发现部署自己的代码的时候一样部署不起来。为什么,我们抛开架构问题时,其实还有一个很主要的问题,我们抛开部署难易度、部署配置管理的问题,还一个很重要的问题,在部署的每一个环节里其实是缺失了监控,他没办法知道我这个部署动作是正常还是异常,所以Right Media后面做了一个很大胆的改革,他要求每一个步骤动作有由开发、测试、运维共同参与,这个其实也是DevOps提供的,甚至是开发都可以去部署,通过这样的一些方法去把我们的代码质量提高,去完善我们的自动化测试,逐步去把一个很大的变更变成若干个很小的变更,变更量、变更代码越小,变更频繁增加,通过一个指标的监控,让整体的发布文化走向完善。


Etsy的案例,黑色线是部署PHP,部署完之后,16点过一点,在这个点部署部署完,PHP告警马上陡增,马上再发布一个东西,然后告警下降,修复了,用更频繁的部署,他每次部署就10分钟,更频繁的部署换来影响更小,我们可以做得更快更可控。整个案例都没有强调说是谁的过错,关键是我们团队怎么样去针对这个过错去修改我们的流程,去共同进步。腾讯的实践方法也类似,通过CMDB把我们的变更跟我们的监控关联起来,然后我们对这个变更对象操作变更的时候,我们的CMDB会有一条变更记录,然后监控系统发现异常的时候,它就会马上直接告警告出来,说我有一个业务告警,这个业务告警发生时这个功能正在变更,请及时处理,让告警更精准,推送到具体的人,实现了MTTI最短的时间,而不是我们收到一个告警还要去分析究竟是什么问题引起的。


要落后这样的发布文化,没办法回避一点,必须要推进我们的非功能规范,无论是我们的监控指标、覆盖度,这些跟业务逻辑无关,你的日志要输出什么能够,你的部署是不是支持独立部署的,是不是具备独立发布的,是不是高可用的等等,都是非功能规范。在书中给了几个实践的方法,大家可以讨论一下在中国是不是可以推行得起来,因为这些全是硅谷的做法。要求开发和运维都是要oncall,轮流值班,今天是你值班,你可能是开发,你值班你来发布或者说发布的告警全部跑到你这,他就有主观能动性,你要降低你的oncall成本,就必须去优化你的代码。还提到了一点,让开发在下游工作,下游就是让开发来干运维的活,让开发自己维护自己的产品。这里我特别想跟大家分享一个腾讯织云实践的案例,腾讯SNG运营部在2008、2009年推行织云标准化,要求所有的开发上线的时候都必须遵循运维的一些非功能的规范,当时运维团队提出了软件包必须要遵循一个包规范,一旦运维发现有开发没有按照这个包规范去发布它的应用程序,当时真实的情况是让开发同学发现这个问题,把不按照规范操作的那个开发人员抓到运维团队去做两周真实工作,这个是真实的案例,这个案例跟谷歌的SRE的实践,不谋而合。


非功能规范,织云也有一些实践案例,运维对应用程序的整个生命周期分成四个阶段,在不同阶段做不同事情,要把非功能规范落实到地,例如运维在开发前会提出的日志标准化格式要求,如JAVA程序、C程序、PHP程序,对应的目录结构、日志存放等。去规范企业内的web服务,尽量集中统一用Nginx。在服务投产上线前会验收,在测试或者持续集成、持续交付的过程中,用织云的运维体系去支持运维的标准化落地,并在运营中持续度量。甚至运维会联合质量管理的QA同学,对研发质量定义出不同纬度的非功能考核的项目,让大家更好的去执行运维标准化的要求,保障每个新应用上线都能有很好的运维支持保障。


投产评审内容,书中提出了一些可供参考的点,如在做发布时应该遵守什么东西,在持续交付的过程中,代码缺陷数量和严重程度到达一定的值,其实这个发布是不允许去投产的。例如在测试过程中或在压测过程中,应用的告警是没办法处理的、没办法看得懂的,不给投产等等,如图内容。这是发布过程中我们必须遵循的技术上的一些考量的点,一些关键的因素。除此之外,站在业务的角度,技术团队还需要去考量一些内容,还需要去关注这个交付、这个部署、这个变更动作会不会影响业务的收入,会不会影响业务的用户量,如果会的话,请在指标上体现这个变更的影响。这个变更会不会有一些高危的风险,会不会有一些监管的风险,像很多金融同行,变更操作必须要符合银监会、证监会、保监会的一些要求等等这些东西。为什么提这种评审的内容,因为DevOps很强调的一个观点,欢迎有存在价值的流程,而不欢迎那些官僚的流程,不欢迎那些为了刷存在感而存在的流程。例如在做发布时,是开发团队和运维团队的事情,但是审批流程需要走到另一个无关紧要的团队来授权,这个无关紧要的团队可能对项目的细节一无所知,这其实就是为了审批而审批,这种流程在DevOps里面,如果用老外的观点,是要严格删除的,这是妨碍组织进步、技术发展的,是业务日益增长的部署效率的需求和落后的审批效率之间的矛盾。

2.2谷歌SRE的运维实践


让发布变得更可靠,Google的案例可以跟大家探讨一下。去年有一本书很火,Google SRE那本书,同样《DevOps Handbook》也是拿Google SRE的案例来举例的。可以这么说,如果按照谷歌对他们应用程序投产的质量要求,可能一个你不要求技能很强的人都能把这个工作做得挺好,因为他的技术文化也好,保障体系也好,其实做了很多这种要求,当然谷歌肯定是招了很优秀的人,但是如果单是从保障这个服务的可靠性来看,不需要很强的技能,都可以把这个服务运维得很好,因为谷歌提出了两个在应用程序或者在产品投产之前的很重要的环节,LRR和HRR,LRR是投产/发布准备就绪审查,审查什么,谷歌SRE团队会给一个检查清单,里面列出了这个程序要投产,必须得符合,书中没有具体描述要符合怎么样的东西,只给了一些举例,假设你一定要高可用,不能写本地硬盘,一定要有状态等等,就是前面所说的非功能规范的要求,跟业务逻辑无关的,但是必须要求开发提前做好。

LRR做不好是没办法走到HRR的,LRR其实是一个投产前供开发、测试和产品团队去自检的流程,是一个软的流程。当走完LRR节可以走到发布投产的环节,发布投产的环节就要走HRR,HRR是什么,用国内的话就是开发把这个服务交接给运维,交接的过程SRE就要来评审,开发是不是符合运维规定的非功能规范,全部做到了,可以进行Hand-off交接,就是开发放手交给运维。然后运维接管维护职责,走到第三个阶段,运维的一段过程中,开发对这个程序有变更,有新的发布,一旦运维发现开发的发布又不符合HRR的要求,这时候运维有权这个应用程序交回给开发,就是一个Hand-back的过程,以这样来制约DevOps经常提的开发要自己吃自己的狗粮,既然你开发的东西难运维、不可运维,那你就自己去运维。这时候开发又要去自己维护,Self-Run,他觉得改进足够了,他又走一次LRR的环节,然后再Hand-off给运维,整个文化在谷歌就是一个很强的文化,你可以认为SRE在谷歌是一个很强势的团队,整个谷歌有超过一百万台物理服务器,他们的SRE团队只有1200人,这是2013年的数据。这是一个DevOps文化的趋势,也很符合让开发自己维护开发的代码,开发在下游工作,你自己体会一下运维的痛苦,如果开发可以通过改一下代码就解决的事情,那千万不要把这个包袱丢给运维。在腾讯的运维实践也做得有点类似,但是终究还是没有像SRE这么强势,所有不标准的发布定夺大部分还是会按产品优先的原则,但是会要求开发在后续工作中修改到标准,是通过考核保障的。

3.提升质量的更多方法

3.1假设驱动开发与A/B测试


怎么样基于监控告警的能力进一步提升业务的质量。这里提到一个假设驱动开发的方法,要把监控能力运用在A/B测试这里,这里也有一个案例,Intuit公司,北美的一个专门做中小型企业财务管理方案的公司,这个公司闷声发大财,2012年利润就有45亿美元,整个公司有8500人,公司CEO和管理团队都很提倡一个文化,他们从来不相信老板和产品经理拍脑袋想出来的产品需求,而是在工程实践、产品实践里和提倡一个文化就是要做A/B测试,Intuit会以最小的产品(MVP)的颗粒度给到他们的用户或者一些重点客户,然后用户来告诉产品经理哪个功能是最想要的,让产品保持迭代,从而去赢得市场,这也是Intuit能够成为这个领域的独角兽的核心能力之一。


A/B测试很早前就有了,电子邮件时代就有一些媒体会发这样的传单给用户,用户来选这个传单里面的这个产品是我需要的,从而来论证这个产品是ok的,那个产品是不ok的,做这样一个A/B测试。A/B测试有一个好处,就像这个图举例,我们对我们的用户群体来做一些样本测试,就像上面这个图,我们是左边放图片还是右边放图片,左边放图片,业务的指标提升了50%,右边放图片只提升了10%,很明显要用左边这个方案。A/B测试今天我们不展开讲,A/B测试同样是依赖于一些技术的要求,业务架构必须满足一些能力,我们才可以开展A/B测试和指标监控,首先我们要能够把我们的用户分群,这一批用户能访问我A服务,这一批用户能访问B服务,这是最基本的,这个其实对业务架构会有一定要求的,这里不展开。


《DevOps Handbook》里为什么提到假设驱动开发,因为他认为传统的开发方法,如瀑布流开发,往往需要一年或者极端情况的几年,才完成一个产品的开发。这个产品无论产品质量和体验做得再好,如果不是用户要的,其实这一段时间是浪费的。这是精益和敏捷的思想,如果产品要做十个零部件,那精益思想希望每个零部件都能独立出来,结合敏捷方法快速实现交付给用户看一下。devops方法提出在做特性监控的时候,能不能有A/B测试的方案,让产品直接交付给用户。在发布版本的时候要用灰度发布的方案,加入遇到用户不买单的情况,那就直接别发布了,停止灰度并全部回滚。换成另一个方案,在特性计划的时候,产品经理规划一个新特性,一定要考虑A/B测试的因素在,这个其实是一个市场营销、用户体验、用户设计等范畴。《DevOps Handbook》推荐了一本《精益创业》,如果大家有负责产品规划,推荐要看一下这本书,讲到了很多方法论,做to c产品怎么做,做to b产品怎么做。


假设驱动开发还有一种做法,这种做法也是业界很通用的叫做漏斗模型,有些地方也叫漏斗获取用户模型的方法,最核心的是怎么样通过用户测试的方法去一层一层看到用户是如何使用产品功能进来的,每跳转一次用户流失了多少,最终注册和付费。之前有个笑话,你看一个网站怎么样去做用户注册的过程,如果你注册一个账号需要五步,那你可能每跳转一步就流失20%的用户,到最后一步可能你的流失率是95%,太多了。但是你看看色情网站是怎么注册的,可能一步就行了。这虽然只是一个玩笑,但如果监控能力能够覆盖这一部分的需求,这个其实就实现了DevOps所提倡的,所有IT团队的工作都是为了实现业务价值,获取用户,这是一种实现业务价值的方法,在定义监控能力的时候也可以去考虑一下,是不是可以帮助到公司的产品人员,帮助公司的市场营销人员,去更好的识别用户的留存率。

3.2优化部署流程中的评审与协调


第三部分最后一个环节,提升质量的方法还是要去不断优化部署流程中评审的过程、协调的过程。书中给了一个方法,这个方法就是GitHub公司真实的案例。GitHub公司对外的产品是GitHub,内部也是严格践行DevOps,其实GitHub很多特性都是他们实践出来的。他们怎么实践出来的,讲一个笑话,GitHub的CIO提过一个笑话,如果我们在提交代码的时候,这个代码的变动只有十行,我们要求另一个程序员给我们做代码审核,十行的代码很有可能给你提出十个问题,但是如果你提交一个变更,这个变更改动了五六百行代码,你还是找回他,同一个同行的程序员给你做代码的交叉审核,他会跟你说,你的代码写得不错,找不到一个问题。这个其实反映了一个问题,我们需要保证我们每次变动它的变化都是最小的,怎么样可以做到最小,其实就是持续交付的一些原则,你必须每天都得提交一次你的代码,或者你一天提交几次,确保你的代码变动量是最小的,这样你才可以去做交叉审查,去做测试驱动开发等等。GitHub公司自己实践出来的,这个特性也在很多GitLab、GitHub都有这种形式,GitHub flow,标准代码提交的过程,应该是什么样子的,首先它是定期的,提交这个代码分支一定要有版本的说明,当他提交完之后会有一个拉请求,去做自动化的编译、测试等等。合到主干分支的时候会有相应的必须的审批流程,审批完之后,合到主干就马上会部署,部署到准生产环境也好,部署到测试环境也好,测试就去测,冒烟测试、集成测试、系统测试,甚至是UI测试,来确保这个代码是ok的,功能提醒是ok的。


这里提到一点,拉请求(pull request),如果大家有用GitHub的经验或者有用Jenkins的经验,pull request大家都应该知道,这个在我们讲DevOps精益文化时,我们提到要怎么样减少浪费,里面提到很重要一点,代码搬运的过程是一个浪费的过程,如果我们不是拉的一个请求,是一个推的请求,假设大梁写完代码了,我给小明提一个需求,我去告诉他说你什么时候有时间去帮我测一下代码,或者我的代码要构建了,这个会有等待的时间,我的代码写出来一直不被人家集成、测试、编译、交叉检查,这时候提出拉请求,很重要一点特征,如果是在GitHub的实现形式,它就是用webhook那种方法,当我的代码上去,这个分支自动就会调用一些自动化的工具,如果是最常见的Jenkins,Pipeline设计好的话,它马上就会去编译或者马上就会调测试工具去测,去降低等待时间,这其实就是pull request。我们先不讨论拉请求怎么样去自动化,《DevOps Handbook》提出了并不是所有的pull request都是pull request,他认为一定要拥有足够充足的上下文信息,它才算是一个pull request,就像右边的这个截图,你必须要写清楚你为什么要变化,你是为了做这样的一个新特性还是为了修复一个bug,还是纯粹为了代码更优雅,变化了什么,改动了哪里,你为什么这样改动,改动完之后有可能影响什么服务,是不是有收入的服务会被影响,你的风险,部署完能不能回滚,怎么回滚,等等,这样才是一个良好的pull request所携带的信息。


这里讲到一个案例,骑士资本,一家做VC业务的投资公司。当年他们有一个很经典的发布,因为一个发布的失败,影响了15分钟,导致他们15分钟交易损失了4.4亿美金,在此之间运维团队在服务部可用的时候是蒙圈的,因为运维没办法回滚,没办法将这个影响降到最低,这个就是因为在运维做变更时,开发人员没把风险说好。这个问题可以有两个角度的看法,第一,怎么样能够更好的去监测到风险与故障,这个是上述刚刚花了很大的篇幅讨论的。第二,能不能在发布过程中,无论是用灰度还是用审批还是用信息共享等等这种方法,让大团队发现这个问题,然后让这个问题不要出现。书中还给了一个最简单直接的方法,当运维发布的时候,面对如此重要的一个影响交易的发布,应该有一个聊天群或微信群,周知和共享信息,让所有相关的团队都可以standby的去应对可能遇到的问题,或者开发跟大家说一下有什么样的风险,让大家提一下建议,他认为这种流程是很有必要的。


这本书提到的一些变更控制的环节,要慎防过度的控制,对变更的控制一定是要把钱都花在刀刃上,怎么样算刀刃上的一些控制呢?这里举了一些方法,书中认为所有对代码质量的控制都是过度的控制,它认为开发人员完成代码开发并提交给测试,测试发现代码质量不高,打回来,然后开发人员再开发。这样一个反复的动作其实都应该在编码环节去解决。参考右边这个图,下面横轴X轴,往左边看是一些审批流程,往右边看是同行开发,代码的质量可以通过一些结对编程的方法,或者说自己研发团队可以解决的一个问题,不应该放在测试环节去解决。这是一个谷歌的案例,这个案例有一条蓝线,往左边的黑点代表审批环节,往右边的黑点代表同行交叉检查环节,越采用交叉检查的代码质量越高,IT的效能越高,这远比走一个僵化的审批流程来得要快,况且很多审批流程,其实又是康威定律作用的,组织架构决定软件架构,既然设立了这样的一个组织,它就必然要去发挥它的价值(刷存在感),就一定要去审批,因为该组织存在就是为了审批的东西。我和很多DevOps同行都有交流,大家往往都会纠结一个问题,究竟企业要实施DevOps,是不是应该推动一些组织结构的变化,这个答案毋庸置疑都是“是的”,但是组织不变同样也能实施,只是实施的没有这么优雅。看了好多北美企业的DevOps实践,他们更容易接纳这种文化,可能国内有很多传统的企业,没办法一蹴而就的接受这种变化,这也是国内DevOps社区想做的,怎么样致力推进DevOps在中国的落地,找到对口中国企业的devops方法很有意义和价值。


怎么样去改进外部审批流程,书中给出了结对编程,下面有两个图,结对编程不是配对编程,不是一男一女的编程,往往是两个男人的编程。书中对结对编程提出了几种不同的方法,有不同的模式,有驾驶员、领航员的模式,驾驶员是主要的写代码的人,领航员负责检查他的代码,但是有一个原则,不要驾驶员写了几千行上万行再给这个领航员去看,而是你每变动一点都要给他去看,这样不仅仅可以促进代码文化标准化的落地,还可以彼此的,相当于也是技能培训。另外领航员也可以旁观者清,他可以更好的根据我们未来规划业务架构所需要的一些技术的方案,他可以给到写代码的人更多的建议。还有Over-the-shoulder这种编程,一个人在写,后面一个人在看,这样你也不能写写代码聊聊微信了,不知道具体欧美怎么执行的。

还有一种跟pull request类似,利用一些工具,GitHub等这样一些工具,提交完代码,他就会把变量的那部分带上你的备注,发给邮件审批人,审批过了再去做。可以通过这个过程的度量,去把它做到足够轻量化。还有一些做法,结合我们的检查工具,例如代码提交,提交到代码库之后,分支之后,会有一些代码静态扫描工具去扫描一下,有控制空函数,也没有野指针,注释量是多少,你有没有引用高维函数等等,都可以把我们研发的流程或者研发质量的一些要求变成一些工具,给他去扫。当然,这里能覆盖一点,但是不能解决所有的问题。还有一些是加强型的TDD,驾驶员写代码,领航员写测试用例,你们同时写,我先写完测试用例,你一提交,马上调用测试用例来测。谷歌在很多场合很多技术分享的时候都表明自己的工程师文化是严格执行TDD的。


结对编程文化有很多好处,也有很多规则,他要求大家一定要提交到主干之前都要交叉检查,你的代码环境有没有什么依赖变化,有没有一些冲突等,一定要定义清楚你是不是有高风险的,如果你认为你这个代码有安全问题,其实是应该有安全专家评审过的,他认为这些在代码阶段所有的问题都是必要的一个流程,我们要结合工具去简化这类流程,但是代码生产出来,所有的风险不要让它遗留在测试阶段,不要让它遗留在投产阶段和运营阶段,必须把影响最小化的扼杀在萌芽阶段。


这里有谷歌的案例,X轴表示代码变化的大小,Y轴是评审的耗时,如果我们每次变更就是十行,可能一个人5分钟就可以评审完,如果变更一万行,他需要一个月甚至是几个月,强调了几点,第一,你每次变更要足够小,频繁去提交你的代码,频繁让别人去看,然后你的代码可读性一定要强,这个自然而然会形成我们团队或者整个企业代码的文化,然后我们的分支管理权限必须要针对这种代码的文化去设计,还有代码的透明度,跨团队的代码管理能力。我印象最深的是当年去硅谷跟他们交流很深的一个印象,当年那个同学他也是在国内工作了一段时间,然后技术移民去了美国,在硅谷工作,我去那边跟他聊,国内外企业的文化差异是什么,他提到一点,你在硅谷入职,你拿到的电脑里面,你打开谷歌的chrome浏览器,里面就已经给你收藏了所有谷歌业务指标的信息,包括业务的关键数据,谷歌认为每个员工都是善良的,既然你成为谷歌团队的一员,你有必要去了解整个公司业务的发展。这个其实挺震撼的,在国内大部分公司相信还做不到这一点,很多老板都担心业务指标被无关的人看到会有机密泄漏或影响估值等风险。挺多这种中西文化的差异,但是我们还是要朝先进的互联网企业去学习。


书中很严肃的提到一点,除了所有有必要的流程,DevOps团队成员应该勇敢的站出来,勇敢的剔除官僚的流程。我也号召大家勇敢的站出来,去给你老板汇报下,对现行不好的流程提出优化方法,运维对生产故障的总结思考能不能够通过代码的阶段去解决,而不是说默默的背了这个锅,这是DevOps不提倡的。z最后欢迎大家后续继续关注DevOps时代社区的拆书活动,一起探讨DevOps落地中国的最佳实践方法。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注