来源 | 混沌工程实践
责编 | 寇雪芹
头图 | 下载于视觉中国
随着Agile和DevOps的持续推进,开发人员获得了软件服务交付更多的权力,交付速度越来越快。在这种持续变更的现实中,随着交付速度的提升和云原生架构的广泛应用,更多的微服务意味着更多的风险。
因为持续且频繁的变更本身就有风险,只不过单次的风险比以前下降了,但由于服务依赖的复杂性带来更棘手的牵一发动全身的级联风险。
有句技术黑话:新技术的应用,往往是把一个空间的问题转移到了另一个空间。前一个空间已有的问题看似不存在了,不过是以一种新的形式出现在后一个空间,有待解决。
云原生应用测试的困境
单体应用的测试思路
过去,开发人员着重在单体应用上,这意味着变更的范围和速率更易于管理。这一直属于持续集成/持续交付(CI/CD)的范围,即测试是在完成开发之后以及开始部署之前要做的事情。
![null](https://i-blog.csdnimg.cn/blog_migrate/a50c10fd808125dba375262d0bf3e045.png)
下图描述的是常见的测试金字塔,说明了我们应该编写哪种测试以及在什么程度上进行测试。可以看到,在测试场景中,向上移动的越多,付出的努力,时间和成本就越多。
如果开发人员很清楚软件的预期状态,他们只要通过单元测试和集成测试验证更改的地方即可。
![null](https://i-blog.csdnimg.cn/blog_migrate/616bbcc159034b6807e52d2ed8447b0b.png)
![null](https://i-blog.csdnimg.cn/blog_migrate/562be02a90784c78e9e2f15c8161f223.png)
微服务应用的测试难度
但是,在将单体应用分解为较小的微服务之后,这种传统的测试定义不再成立。
我经常听到有许多公司试图在开发人员的本地环境上复制整个应用拓扑。以前我们用的是vagrant up
,现在可能是docker compose
。
开发人员应该能够在本地运行整个环境。
人们开始以单一的思维方式来构建微服务,跨越众多服务的大规模集成测试是一种反模式。
转向微服务还意味着使用正确的工具和技术。
如果我的应用由100个微服务组成,CI/CD根本无法同时构建和测试(真有公司这么做,其复杂程度令人惊悚)。
新功能发布时,由于微服务的颗粒度很小,只要个别微服务通过CI/CD重新发布,而且其他大多数微服务将会在生产上继续运行。
在这种情况下,以前单体应用开发人员对软件状态的理想预设,在这里就成幻象。
微服务之间的级联依赖和持续的增量变更,很可能导致整体应用的状态难于预测。
这就好比,时速120公里的轿车和时速300公里以上的F1赛车,两者的安全措施完全不是一回事。
因此,我们需要新的测试模式。
故障发生是新常态
根据谷歌云2019年的DevOps现状报告,变更故障次数最高能占到所有新代码发布次数的60%,由于是工程师问卷反馈的统计,实际的失败率很可能更高。
https://services.google.com/fh/files/misc/state-of-devops-2019.pdf
云原生时代,我们心中松耦合的微服务架构可能长这个样子:
![null](https://i-blog.csdnimg.cn/blog_migrate/e4e41104d84787e8cb588868d10bc7ab.png)
但在实际的生产中,下面这张图更接近于现状:
![null](https://i-blog.csdnimg.cn/blog_migrate/4173398dc3119c24519ec38f1ada7a1c.png)
负载均衡器ELB不知道所有的网关实例,或者由于防火墙规则而无法在网络中找到它们。
好几个服务实例已死,但是服务发现并没有注意到这个情况。
服务发现的节点之间无法同步,产生了网络分区,数据一致性被破坏。
由于只有一个网关实例,因此无法分配负载,导致该节点上的负载持续增加。
当我们处理多达几十个实例的小型系统时,100%的健康运行通常是正常状态,故障则是一种特殊情况。然而,在处理大规模分布式系统时,即100%的健康运行几乎是不可能实现的。
此时,我们必须接受故障发生是新常态的现实。
大家深有体会,我们不能再等了!
![null](https://i-blog.csdnimg.cn/blog_migrate/27edfb592cd5565d79045a5cea366ccb.png)
需要一条新的出路
可观测性令测试向右移
分布式追踪结合传统的指标和日志监控,随着可观测性技术的出现,将代码推入生产并观察服务接口的错误率,成为一种符合现实的策略。
如果其他微服务出现问题,接口错误率就会很快显现出来,此时可以选择修复或回滚。这基本上就是在让可观测性系统承担回归测试的功能和原先CI/CD所扮演的角色。
不过,开发人员视生产神圣不可侵犯,对相同的制品仅在类生产中进行验证。这是他们从职业生涯开始就已扎根于心的东西,而对实时流量进行监控和追踪,这是运维工程师要做的事。
因此,我们需要思维方式的转变,迎接“测试向右移”,接纳可观测性技术,向在生产中测试挺进!
探索性测试焕发新生
探索性测试(Exploratory Testing)是由Cem Caner首次提出,80年代就一直存在的测试方法,2011年James Whittaker出版《探索式软件测试》后,在业内引起广泛关注。
探索性测试可以说是一种测试思维技术,主要由经验丰富的测试人员实施。该方法能够基于已有的知识、启发式的理念和风险领域在有限的时间内挖掘出更有附加值的问题。
Netflix提出了混沌工程
![null](https://i-blog.csdnimg.cn/blog_migrate/a1894a524fbd4179b29d04d94635e154.png)
Netflix在十年之前,接受了故障发生是新常态的现实,在探索云原生的过程中,巧妙地将探索性测试方法和可观测性技术结合在一起,以生产实验的形式,随机注入故障,通过可观测性技术,探查系统行为变化,突破人对系统的认知盲点。
只有人对其研发的系统有更加深入的认识,才能真正提高系统本身的韧性。
结语
本文从云原生应用测试的困境出发,借以单体应用的测试思路,衡量微服务应用测试的误区和难度,表明了我们需要改变对测试固有思维模式的决心。打开视野,接受故障发生是新常态的现实,迎接云原生应用测试新的出路。
有意思的事,近年来可观测性技术突飞猛进,给云原生应用在生产中进行测试提供了极佳的现实支撑。开发人员要改变固有的思维模式,不能满足于仅在类生产中测试的现状,要推动测试向右移,利用可观测性技术,在生产中进行探索性实验。
Netflix是最早吃螃蟹的,第一个提出了混沌工程的理念和方法,将探索性测试方法和可观测性技术结合在一起,助力开发人员在生产中进行实验,最终的目的还是为了加深开发人员对于系统行为的认识,促进系统架构的韧性。
2020-2021中国开发者调查报告重磅来袭,直接扫码或微信搜索「CSDN」公众号,后台回复关键词「开发者」,快速获取完整的报告内容!
更多精彩推荐
☞云原生全景图之六 | 托管 Kubernetes 和 PaaS 解决什么问题☞继云计算巨头失火后,微软决定送数据中心去“泡澡”!☞走过 30 年:银行数据库的下一步是国产化
点分享点收藏点点赞点在看