容器架构下的性能测试实践方法
技术交流群看到这样一个问题:服务部署方式改成了容器化,要根据业务场景和不同的参数配置进行性能摸底,找到最佳配置,性能测试该如何执行?看似很简单的性能需求,其实难度并不低。
首先,容器化部署和常规的虚拟机/云服务部署存在一定区别;其次,涉及到业务场景就需要考虑真实的业务模型和流量模型;
再次,在容器化部署的不同配置下性能表现的差异很大;最后,是满足业务需求的最佳配置。其中还未考虑外部依赖的影响,以及如何应对线上突增流量的场景。
这篇文章,以这个需求为案例,谈谈我的理解和实践方法。
一分钟快速了解容器化
容器化部署,简单来说就是一种轻量的虚拟方法,将应用程序及其依赖项(包括操作系统)打包,使其可以便捷的跨平台和系统运行。
目前大家熟知的Docker和Kubernetes,已经是十年前出现的技术了,而容器化相关的概念和小范围实践,可以追溯到1979年Linux系统的chroot调用方法。
容器化在服务部署和跨平台应用方面,有很多方面的优势,主要如下:
- 可扩展,可以有效地分配资源(共享操作系统内核,降低性能损失)。
- 可移植,构建一次在任何地方运行(基于宿主内核运行,在任何支持容器的操作系统上运行)。
- 速度快,共享主机操作系统内核,无需启动完整操作系统,降低额外开销,可以做到毫秒级启动。
- 管理方便,可以快速的部署和管理应用程序,资源控制粒度更细,通过命名空间和控制组,灵活分配资源。
以本文开头的问题为例,我个人认为针对该需求的性能测试可以按照如下方式开展。
第一步:确定业务和流量模型
既然是性能摸底,一般都会选择一个典型的业务应用来做验证。毕竟是性能测试,脱离实际的业务场景直接开展性能测试就显得捡芝麻丢西瓜。
假设选择了一个订单应用,那这个应用的核心业务场景有创建订单、订单支付、订单列表、订单详情等,根据要验证的具体的业务场景,通过线上监控和历史数据分析,得到一个相对准确的流量模型是很有必要的。
否则流量模型不对,那得到的性能数据也没有太多的说服力,且压测所需用到的测试数据也可能会不够精准,最终导致测试结果南辕北辙。
关于业务模型、流量模型和数据模型,详情请看:《构建三大模型》。
第二步:确定最佳性能预期指标
做性能测试很忌讳的一点就是先测试再定指标,这样很容易导致重复的返工和拉扯。毕竟测试是个验证的工作,没有预期的指标就开展,就像拿着锤子去砸,砸到谁谁就是钉子一样。
即使最开始没有明确的性能指标,也要通过分析需求和沟通,确定几个指标,这样后续的测试活动开展才有方向。以本文开头的问题为例,可以从如下几点来考虑制订预期指标。
- 单pod的CPU使用率要限制在多少?
- 99%响应时间和平均响应时间在多少范围内?
- pod的CPU核数是固定还是范围内弹性?弹性范围是多少?
- 单pod向集群模式扩展,集群的性能衰减系数要控制在多少?
通过以上几点确定明确的指标,后续的测试活动开展才能有的放矢。
第三步:制订详细的性能测试任务
明确了业务和流量模型,有了明确的性能指标之后,接下来就是制订详细的性能测试任务。下面列举几个任务,便于大家更直观的理解。
1、验证单pod的极限性能
假设单pod固定配置为2C4G,通过压测得到该pod在CPU/memery使用率打满情况下的性能表现。
2、验证单pod的最优性能
假设单pod固定配置为2C4G,CPU%必须<60%,通过压测监控得到在CPU%<60%时对应的TPS/99RT(当然,也可以限制99RT的最大值,观察pod的资源使用率)。
最优性能的定义一般需要具有这两个特性:业务可接受+系统稳定性可接受。我们常提到的性能拐点,就是这个目的下的典型案例。
3、验证固定配置下的集群扩展能力
假设单pod固定配置为2C4G,当CPU%>60%/ART>80ms时自动开始增加pod数量,通过压测监控观察扩容时是否存在异常,以及扩容后的性能表现是否和集群数量的增加成正比例。
4、验证弹性配置下的集群扩展能力
假设单pod固定配置为2C4G,当CPU%>60%/ART>80ms时自动开始提升pod配置(比如从2C4G升级到4G8G),通过压测监控观察pod升配置时的性能变化是否正常,以及升配置后的性能变化是否符合预期。
5、验证异常场景下的集群扩展能力
在不断增加并发的情况下,让弹性扩容的一部分pod挂掉,观察pod挂掉之后是否有新的pod继续扩容,还是扩容动作到此停止。
当然异常场景有很多,比如将扩容的pod从集群中T出去,比如是否触发限流和熔断,比如大量的请求异常情况。
除了上述动作之外,还需要考虑其他因素,比如外部依赖调用如何处理(常见的方式就是mock),比如应用集群依赖的一些中间件参数配置要调整,保持一定冗余,否则容易出现pod集群扩容了,其他组件性能没跟上导致的尴尬场面。
当然,上述五个压测任务可以互相组合,验证更多场景下的性能表现,如何组合取决于性能测试的目的和预期的目标。