稳定性测试与监控——云原生测试实战(3)

发表于:2024-2-17 09:23

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:孙高飞    来源:51Testing软件测试网原创

  第6章 稳定性测试与监控
  相信很多读者在看到本章的标题后都会有一些疑惑,稳定性这个概念似乎与第4章讲述的高可用很相似,在业界确实有些公司会把高可用测试叫成稳定性测试。本章将详细介绍稳定性测试的所有细节。
  6.1 什么是稳定性测试
  接触过移动端的App自动遍历技术的读者,理解稳定性测试会相对容易。它们的测试目标是类似的,只不过一个是针对客户端,一个是针对整个系统。App自动遍历技术是指在一段比较长的时间内不停地点击App中的控件来模拟用户长时间使用App的场景,目的是验证用户长时间使用App会不会导致其出现崩溃、闪退、卡顿、OOM等异常事件。软件中很多缺陷不会在刚开始运行的时候就显露出来,而是随着运行时间和数据量的积累才会慢慢暴露出来,例如泄漏类的缺陷(内存泄漏、文件描述符泄漏等)和部分在并发场景下才会出现的缺陷。所以,稳定性测试的定义是:在一定的并发量下,验证系统在长时间运行的过程中是否可以持续、稳定地提供服务。
  虽然稳定性测试与移动端的App自动遍历技术有异曲同工之处,但是稳定性测试更加复杂和严格,并不能把App自动遍历技术的思路照搬到稳定性测试中来,而需要明确稳定性测试中的关键要素,这些要素具体如下。
  一定的并发量。有不少的缺陷是在并发场景中才会出现的,例如在旧版本的Go语言中并发写Map的问题是经常能遇到的。所以,与App自动遍历技术的单线程执行不同的是,我们需要用一定的并发量来对产品进行测试。
  关注业务结果。App自动化遍历技术是使用一定的算法去自动点击App上的控件,并不需要判断业务属性,只需要验证App在运行过程中是否有闪退等情况出现即可。而稳定性测试需要运行的是能够覆盖大部分业务的自动化测试,除了要验证服务是否崩溃、OOM、发生泄漏,还要验证测试用例能否成功运行完毕。这一点需要我们的自动化测试工程是足够稳定的。
  关注数据增长。很多缺陷随着系统中数据量的增长才会逐渐显露出来。例如,在K8s中比较容易出现的一个问题是系统动态创建的各种资源对象没有清理,导致数据量堆积,最终造成整个系统的异常。这个问题经常发生在大数据和AI类型的产品中。每提交一个离线计算任务都相当于创建了一个或者多个Job对象。Job对象运行结束后虽然会对Pod进行自动回收,但是Job对象本身会一直留在系统中。如果开发人员没有设计清理这些Job对象的机制,随着时间的推移最终会引发系统异常。这一点与第4章中的驱逐策略引发的大量驱逐记录是一样的。
  监控系统的构建。移动端的App自动遍历技术不需要监控系统的配合,它的关注对象只有当前的App。而稳定性测试不同,它需要关注系统中数百个服务的运行状态。一旦有任何服务出现异常,都需要进行告警并抓取关键的日志、错误码等信息帮助测试人员和开发人员分析问题。这里需要注意的是,K8s拥有强大的自动化运维能力,异常的服务可以在短时间内被K8s重启或重新调度以恢复正常,很多时候测试人员甚至感知不到服务曾经出现过问题从而漏掉缺陷。所以,构建一个基于事件驱动的监控系统来捕捉瞬时事件的能力是很关键的。
  通过上述的分析我们可以知道,稳定性测试技术的关键在于以下两点:
  ·稳定的、大规模的、业务级别的自动化测试工程;
  · 基于事件驱动的监控系统。
  第一点不在本书的讨论范围内,我们接下来着重关注如何构建一个基于事件驱动的监控系统。
  6.2 List-Watch
  在第5章中详细介绍过Prometheus的使用方式,但因为Prometheus依赖周期性的抓取策略来获取监控数据,默认情况下无法很好地描述环境的瞬时状态,所以它对测试人员来说仍稍显不足。虽然通过特殊的PromQL和Pushgateway可以间接地达到一定的效果,但是仍然无法从服务中获取容器崩溃的信息(基本信息、错误码、日志等)。简而言之,Prometheus更擅长分析系统长时间的运行状况,却不擅长收集和上报瞬时事件的数据。通过前文的介绍可以得知,这种对瞬时异常的告警分析能力对稳定性测试来说是至关重要的。
  6.2.1 K8s的控制器模型
  K8s的List-Watch机制可以很好地弥补Prometheus的不足。在详细描述它的使用方法之前,先简单介绍一下K8s的控制器模型。
  在K8s中存在诸多控制器,这些控制器用来维护每种对象的状态,Pod对象有Pod控制器,Deployment对象有Deployment控制器,理论上每种对象都有对应的控制器。这些控制器会处理用户针对该类型对象的操作请求,同时也会维护它们在集群中的状态。例如,在K8s中当用户希望修改某个对象(Pod、Deployment、Service等)的配置时,最常见的做法并不是通过kubectl命令去修改对象中的字段,而是编辑当初创建这个对象时提交到集群中的YAML文件。文件修改完成后便可通过kubectlapply-f{文件路径}的方式将其提交到集群中,K8s会自动识别新的配置文件和当前集群中已经运行的对象之间的差异并进行更新,而完成这个任务的正是在K8s中运行的各种控制器。理论上每种对象都会有特定的控制器来进行维护,这些控制器的逻辑类似代码清单6-1中的伪代码。
  代码清单6-1控制循环:
  for {
      实际状态 := 获取集群中对象的实际状态(ActualState)
      期望状态 := 获取集群中对象的期望状态(DesiredState) 
      if 实际状态 == 期望状态 {
            什么都不做
          } else {
            执行编排动作,将实际状态调整为期望状态
          }
  }
  根据代码清单6-1可以得知K8s与常规软件不一样的是,用户并不直接提交具体修改了哪个字段,而是提交一份完整的对象配置。控制器会不停地去获取APIServer中对象的最新配置并与集群中对应对象的实际状态进行对比,最终把对象更新成用户期望的样子,这一过程被称为控制循环。
  在整个控制循环中,最重要的是确保控制器和APIServer之间消息传输的可靠性和稳定性,并且还需要拥有一定的实时性,毕竟延迟过高会给用户带来很不好的体验。一般来说,如果要保证消息一定程度的实时性,在业界最常见的方法是客户端周期性地轮询服务器端,但采用轮询势必会很大程度地增加APIServer的压力从而严重影响K8s的性能,并且轮询的实时性并不好。为了解决这个问题,K8s设计出了List-Watch机制,接下来我们详细介绍一下List-Watch的原理。
查看《云原生测试实战》全部连载章节
版权声明:51Testing软件测试网获得作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号