相信大家对 TDD (测试驱动开发)、 BDD (行为驱动开发)、 MDD (模型驱动开发)和 DDD
(领域驱动开发)都已经很熟悉了,然而今天大叔想介绍的是另一种 MDD ,指标( Metrics )驱动开发:Metrics-Driven
Development,当然,这里的 M 如果换成 Monitoring 的话,其实意思也是差不多的,即 Monitoring-Driven
Developmnt (监控驱动开发)。
什么是 Metrics-Driven Development
MDD 这一说法最先被提出,应该还是 Etsy 这家公司的工程师 Mike Brittain , Etsy 这家公司也很伟大,开源了很多软件,比如 Statsd ,一个用于收集、转发 Metrics 的软件和协议,现在被很多监控软件所采用。
在
2011年3月12日 (
https://codeascraft.com/2011/03/01/moving-fast-at-scale-sxsw/ )的 SXSW
期间, Etsy 举行了一个小小的活动,向外界集中介绍了一些他们在进行快速产品迭代、发布上的一些经验,这个活动的主题就是 “Moving
Fast at Scale” 。Mike Brittain (当时核心平台部的负责人,现移动产品工程总监)在这次活动中进行了主题为
“Metrics-driven Engineering at Etsy” 的演讲,提出了 Metrics-Driven Development
这个相关概念。
Metrics-Driven Development 的意义
为什么会有人提出 Metrics-Driven Development 这个概念呢?在进入正题之前,我们还是先来回顾下 TDD 。
TDD 是测试驱动开发( Test-Driven Development )的英文缩写,也是敏捷开发中的一项核心实践和方法论。TDD 的思想是在开发功能代码之前,先编写测试用例代码,用于测试代码是否能满足设计之初的需求。
测试代码不是简单地测试,TDD 是通过这种方式,是将测试贯穿到整个开发过程,提高测试的可靠性和重要性。
需求分析和需求变更历来都是软件工程中一项难度比较大、风险性较高的工作,测试驱动就是通过测试用例,让开发者在早期阶段就考虑到代码层面的设计和编写,以及如何验证需求的问题,确保以一种代码化、自动化的方式来进行需求验证。
和 TDD 类似,既然可以在写业务代码之前先编写测试代码,那我们是不是可以考虑得更长远一些,将上线、监控、调试和故障调查以及优化也纳入到设计阶段来做?
回到上面图中的这句话,也就是说,你都不能衡量一个东西,你怎么去管理它呢?(至于这句话到底是 Edwards Deming 说的,还是 Peter
Drucker 说的,我们就先不去追究了 ... ...)
所以,也可以说 MDD 是这句管理学中的名言在软件开发领域的一个实践。
什么是 MDD 呢?这也是一种开发理念,或者叫做哲学,即 通过实时指标来驱动快速、精确和细粒度的软件迭代 。
The use of real-time metrics to drive rapid, precise, and granular software iterations.
MDD
的创新之处在于将应用程序(服务)的监控( Metrics )提高到系统整体这一层次,在设计初期就开始将 Metrics
设计也包括进来,就如同写代码之前,先写测试用来一样。也就是说,未雨绸缪,在系统出问题之前,在系统设计之初,就设计一套规则来评价系统的稳定性、健康状态以及其他各种的考核目标(即服务本身的
KPI)。
一言以概之, MDD 可以帮助我们更早地 发现问题 和 明确目标 。从一定意义上来说, MDD 也是大数据。
我们都知道,监控的主要目的是为了发现问题。但是除了能及时、没有遗漏地帮我们发现问题之外, MDD 带来的另一个好处是通过对现状的可视化和具体化,来帮助我们对未来进行规划和预测,进而实现业务改善。
比如可以根据当前服务器内存使用率、网络带宽这些基础设施因素及趋势,预测未来一段时间的容量规划。
相对于传统上通过制定各种复杂、严格的研发规定,以及无数的评审、研讨会议来确保软件安全发布、稳定运行,
MDD 理念的特别之处在于在应用程序本身中,采集必要的监控信息,通过持续交付方式,进行快速迭代并进行反馈和修正(请参考一下 PDCA 环或者
OODA 环的相关知识),所有决定都是基于对不断变化的情况的观察。
总之呢,毕竟要穿几尺腰的裤子,拦腰虎抱不准,目测不灵,还是得量量才知道。
图片来自: http://www.jituwang.com/tuku/201305/295805.html
程序运行起来才能为用户提供服务,才能为用户提供价值,为公司赚取收入;躺在 Git 仓库中的代码,编码风格再好,注释再详细,如果没有运行,并没有一毛钱的用处。
对于静态代码我们有各种工具和原则来进行管理,对于运行中的代码, Metrics 能为我们提供整个系统的详细情况,哪些代码执行过,执行过多少次,哪里有错误,有多少错误,都能让我们一目了然。
Metrics 不仅对软件系统而言必不可少,对业务系统来说,也能作为决策的强有力的根据,帮助我们减少犯错、提高决策速度和精准程度。
理论上来说,能被具体化、数字化的指标,都可以进行提高和优化,进而驱动业务提升,带来更多的商业价值。
MDD 定义中的快速、细粒度迭代等词眼,也是和 DevOps 等现代软件开发理念契合的。也可以说, MDD 基于敏捷开发、持续集成和持续交付这些软件开发方法论和实践发展而来。
DevOps 强调随时发布,每次细小修改发布之间,都可以通过 Metrics 来监控发布后所带来的各种指标的变动,快速发现问题,或者提供业务数据反馈。
MDD 和传统的 Ops 的最大区别,可能就是需要更多的从开发者的角度去设计这个 Metrics (监控)系统。即需要开发者在监控方面发挥很大的主观能动性。
在传统开发文化上 Dev 和 Ops 是割裂的, Ops 不懂程序,不知道如何优化程序,而 Dev 不懂基础设施和中间件,DevOps 不只是沟通上的变化,对双方的技能也有要求,不知道 load1 、load5 、 load15 的开发者估计再不学习工作都要不保了吧 :-(
图片来自: https://www.linkedin.com/pulse/essential-devops-skills-thomas-theakanath
关联性分析一直是智能运维中的一个重要组成方面。通过关联性分析,可以从一个现象找到关联现象出现此现象的原因,或者其规律。
举例来说,将用户下单数量、 HTTP 请求成功率和数据库连接错误这 3 条线摆在一起,你可能一眼就知道,哦,原来是数据库老连不上,导致 HTTP 请求错误率居高不下,进而影响到了用户下单数量。
要实现关联性分析的第一步,就是数据收集,开发、运维首先需要能收集到足够详实和精细的数据,才能为建立指标关联关系、挖掘指标趋势的因果关系打下基础。
不管是从软件工程阶段还是覆盖的应用各组成部分来说,传统的测试方式还是有一定的局限性,势必会有一些遗漏。单元测试不能模拟用户行为,集成测试不能覆盖整个用例流程,压力测试不能再现真实负载,所有的测试加在一起,也不能完全覆盖生产系统的实际运行情况。
而 Metrics 则可以作为测试系统的补充,而且是,是在服务已经发布上线之后。通过收集服务运行中的 Metrics 数据,可以判断是否服务在平稳运行中,找到出错的地方,甚至可以预测服务的未来发展趋势。
图片来自:https://zh.wikipedia.org/wiki/%E4%BE%A6%E5%AF%9F%E6%9C%BA
Metrics 分为 3 个级别:
Infrastructure / System metrics,比如服务器状态、网络状态、流量等
Service / Application metrics,每个 API 的耗时,错误次数等
Business metrics,即运营数据或者业务数据,比如单位时间订单数、支付成功率、日活月活。
其中面向业务的 Metrics 用处就更多了,比如还可以用于帮助我们进行 A/B 测试、打印 KPI 报表等。
其中,第一种
Metrics 其实传统的 Ops 已经纳入其中了,即基础设施的监控,而第二种监控,我们可能更多的是通过中间件监控(这里包括类似 Nginx
或者 Tomcat 等软件)或者 APM 软件来实现,而第三种,一般都是通过第三方统计工具来实现,比如 Google analytics
这样的产品。
MDD 中,则尽量会将这些 Metrics 统一起来。
即设计时,要求提供 Metrics 接口都成为一个基本要求,甚至可以在评审或者上线时,将 Metrics 功能作为重要评价成分。
举例来说,我们可以要求每个服务都需要提供一个 /metrics 接口来暴露内部监控数据,进而展示服务的运行状态。
和 DevOps 类似,MDD 不光是一种技术上的变化,还是一种文化、流程和工具上的变化。开发者要学习基础设施的知识,Dev 和 Ops 还需要和运营等各非技术部门的人员交流,这都是对传统文化的一种挑战。
如何实现 Metrics-Driven Development
实现上需要考虑的点很多,比如采用什么传输方式和协议,这里讲 2 点重要的:
先说存储。
从投入形式上来说,有两种,即自己设计、研发搭建并维护一套 Metrics 采集、展示系统;第二种选择就是采用 MaaS(Metrics as a Service)。
MaaS 就像 SaaS,其优点就是开箱即用,入手简单,但时间长了,就会暴露出一些问题,比如功能定制困难(有些功能实现不了)、性能降低(网络延迟等),以及费用昂贵等。
所以,规模达到一定程度,尽量还是自建吧。
Librato 是一个 MaaS 服务的典型代表。
自建的话选择也很多,可以选择纯粹的
TSDB 数据库,比如 InfluxDB ( https://www.influxdata.com/ )或者 OpenTSDB (
http://opentsdb.net/ )这样的软件,或者采用一些专门为 OLAP 设计的软件,比如 Druid (
http://druid.io/ )、 Kylin ( http://kylin.apache.org/ ) 等。
其实建设这样一个
Metrics 系统的难点在于一体化,即将 3 个维度(基础设施、应用和业务即运营)的 Metrics
放到一块。这在开发上势必投入成本比较大,首先需要将 DevOps
融入进来,还可能需要将运营人员加入,将托管在第三方平台或者软件上的数据迁移到自己的 Metrics 系统上,可能最大的开发量在这里吧。
再说打点这个功能,主要涉及到第二种 Metrics ,即应用程序自己的 Metrics 。这个就完全由开发人员自由发挥了,framework 的 hook 功能一般都是个不错的选择,具体的也可以参考 APM 软件的实现方式。
其次就是可以使用类似 Java 的 Annotation 或者 Python 的 Decorator 来实现,从技术上来说都很容易实现,也都有很多案例可以参考。
图片来自: http://fond-sblizhenie.ru/opredeleny-pilotnye-regiony-v-kotoryx-projdet-aprobaciya-sistemy-monitoringa-sostoyaniya-mezhnacionalnyx-otnoshenij-i-rannego-preduprezhdeniya-mezhnacionalnyx-konfliktov/
到这里,大叔就为大家简单介绍了 MDD 的一些东西,零零散散,不成体系,只希望能给大家带来些参考,结合自己的项目,评价下是否 MDD 值得展开。
如果能帮到你,大叔也就没白码这么多字。谢谢阅读。
参考:
Metrics-Driven Development: https://www.infoq.com/articles/metrics-driven-development
Metrics-Driven Development: https://sookocheff.com/post/mdd/mdd/
Metrics-Driven Development: http://blog.librato.com/posts/2014/7/16/metrics-driven-development
Metrics-Driven Development: See the forest for the trees:http://www.roguelynn.com/words/metrics-driven-development/
Moving Fast at Scale: a microconference at SXSW: https://codeascraft.com/2011/03/01/moving-fast-at-scale-sxsw/
Metrics, Metrics, Everywhere - Coda Hale: https://codahale.com/codeconf-2011-04-09-metrics-metrics-everywhere.pdf