性能工程,是指通过设计、构建工具链和工作流,从而对系统性能进行持续改善和守护的一类实践方法。
本文将从起源开始探寻性能工程出现的必然性,进而以软件研发流程中处理性能问题和实施性能优化时所遇到的挑战为出发点,来讨论性能工程的定义以及企业实践性能工程的目标。
性能后置时代落幕
近 30 年的互联网大爆炸,让各类传统业务领域通过数字化迅速在互联网蓝海中占领自己的位置,从而实现了业绩高增长和投资高回报。
大量投资推动了计算机技术的极大发展,也反过来影响了在线业务的企业:只要乘着技术发展的东风,就能让单位服务成本越来越低,而速度越来越快。
无论是通过调研数据还是从业者自身的感受,我们都会发现,性能是在整个研发流程中被不断后置的。架构设计优先考虑功能,代码研发也是主要关心业务,测试环节除了验证业务正确性,留给性能测试的时间少得可怜,还经常遇到人力不足,那就“先上线再说”。
然而,这种性能后置,甚至无需考虑性能的时代可能即将落幕了。原因有三:
1. 计算机体系结构发展放缓
上图展示了处理器性能在近 40 年间的发展趋势。1986 年开始到 2003 年这段时间,处理器性能每年增加 52%,17 年性能翻了 25 倍。然而由于登纳德缩放比例定律的终结,单核性能无法再增长,导致 2003 年开始性能增长的方向从单核转向了多核,性能增速有所降低,但也依然称得上高增长。然而,随着摩尔定律的逐渐失效,2015 年开始年均性能增速仅剩 3.5%,这种速度与先前相比可谓几乎停滞了。
另外,在单核处理器主流的年代,处理器主要通过指令级并行来提升性能,这对软件开发来说几乎无感。而多核时代到来后,主要通过数据级并行(例如 SIMD)和线程级并行(多任务)来提升性能,这种优化很依赖代码设计,因此对程序员也提出了更高的要求。
总之,如果不发生大的技术变革,软件性能再也无法简单的通过硬件的更新而大幅增长了,然而随着各种新奇功能的出现,用户对性能提升的需求却丝毫未减。
2. 复杂系统性能治理愈发困难
与硬件不同,得益于高度灵活的架构,软件一直朝着扩大规模的方向发展。为了治理不断膨胀的软件规模,软件架构从早年的单体应用逐步发展到 SOA 架构,再到分布式、微服务架构和云原生技术等。如今的软件系统规模越来越大,越来越复杂,只有通过不断的分层和分治才能有效的对其进行控制和演进。
然而,正因为对系统架构的拆分,导致服务间的交互早已不再是单个函数的调用,而是跨进程调用甚至远程调用。正如上图所示的Uber 的微服务架构图,复杂的调用链路上任何一个环节都有可能存在性能瓶颈。系统间依赖的复杂度越高,出现性能阻塞点的概率就越大,如果不加以治理,其结果就是运行低效和难以扩展。
3. 无法忽视的成本增速
随着在线业务的逐渐饱和,叠加多变的经济形势,企业越来越感受到基础设施的巨大成本对经营产生的显著影响。
据2023 State of the Cloud Report显示,云成本管理十年来第一次超过了云安全,成为企业用云的头号挑战。同时,公有云支出平均超出企业预算 18%,并且云成本仍在逐年增长。成本的增长驱使人们想尽办法提升资源的利用率和分配效率,这也引领了近些年虚拟化技术和容器化技术的发展趋势。
但在 CNCF 发布的 FINOPS FOR KUBERNETES 中显示,即便在容器技术大幅提升资源利用率的情况下,仍有 68% 的企业表示在迁移至 K8s 后其计算资源成本反倒增加了。毕竟,迁移 K8s 给系统引入了新的复杂度,也引入了适配和学习的隐性成本。
通过对系统进行更深层次的观测,发现性能劣化问题和性能阻塞点进而优化性能,能够在提供同样服务水平的前提下降低硬件开销,充分利用硬件算力,并改善用户体验,从而在多个角度降低成本。因此在如今这样成本敏感的时代,性能优化意义非凡。
融入性能并不容易
即便是软件性能比以往任何时候都更重要,但想要顺利地把性能融入研发工作流,却并不是件容易的事。
首先,现有的成熟研发流程中,性能往往被忽视。
正如前文提到的,现有研发流程一般只会在测试阶段安排少量性能测试内容,而其他各研发环节都没有对性能形成固定的认识。
设计阶段,架构师通常会基于自身的经验和知识,进行一定程度的性能考量,但大都不会输出完整的性能建模方案和验证方法。
开发阶段,程序员也是在完成业务开发之余,零散的写一些性能相关的代码,且不太可能提供完整的性能测试用例。
测试阶段,虽然有性能测试,但是否覆盖了关键性能路径?测试方法是否存在偏颇?也是一笔糊涂账。抓紧测完按时上线永远是第一位。
上述流程现状实际上是把性能问题推到了 Day2。测试阶段发现性能问题已经很迟,而倘若上线后再出性能故障,一定会大动干戈,伤筋动骨,甚至要调整架构。习惯了“性能后置”,想要打破现有流程,引入新的环节,对已经形成思维定式的研发团队实在是很不容易。
其次,性能优化非常依赖专家经验,难以规模化。
性能问题是复杂且多样的,其场景可能介于 Cynifin 框架中 Complicated 和 Complex 之间,需要通过对问题审慎的分析和对系统深入的洞察才有可能找到正确的优化路径。
性能优化的实施者不仅需要对被分析系统的整体架构和关键业务路径有清晰的认识,还要掌握系统层面的基础知识和原理,以及各种性能分析工具的使用。此外,为了提升定位问题和寻找优化方向的成功率,性能优化方法和理论以及大量的实践经验也不可或缺。
以上要求对一般的研发人员来说挑战极大,因此实际当中遇到性能问题往往需要依赖性能专家和领域专家的共同努力,但面对多种多样的性能问题,专家资源往往“捉襟见肘”,增加时间成本的同时也难以规模化推进性能改进。
再次,孤立工具给研发人员造成了极高的认知负载。
正因专家资源的稀缺性,性能优化通常会首先由研发人员尝试介入。实施优化的前提是数据收集和问题分析,即便是如今的可观测系统越来越强大,但在进行性能分析和系统剖析时大都还是会依赖外部采集分析工具。
然而,现实是不同的编程语言、技术框架、中间件和操作系统都有自己的一套实用工具,这些工具之间的使用存在差异,关注点与数据格式也不尽相同。对各种工具的熟悉和使用存在可观的成本与学习负担,也导致对人员能力的特殊需求。
有过分析性能问题经验的人都知道,选择并使用数种工具,在众多的运行结果中进行数据关联来寻找问题踪迹,是性能分析和优化工作的日常。由于数据缺少关联性,展现形式也不够直观,使得这类分析工作存在巨大的认知负载。对大多数应用开发者来说,这种高认知负载导致了在性能优化工作上的巨大负担。
落地工程化方法——性能工程
基于前面提到的在实施性能优化过程中的问题和挑战,我们期望通过设计、构建工具链和研发工作流,来落地称为 “性能工程” 的工程化方法,以实现标准化和规模化的系统性能持续改善及守护。
为了明确这种工程化方案的内涵以更好的指导工程落地,我们尝试定义性能工程的目标:
DevPerfOps:构建性能工程反馈闭环
为了改变研发工作流中忽视性能的现状,通过在完整 DevOps 流中引入性能工程改造点,以实现嵌入性能工程的研发工作流反馈闭环。
架构设计阶段,引入性能建模过程,产出对系统总体性能目标的定义和指标要求,以及在系统架构层面的性能建模,和性能关注点地图。
代码研发阶段,根据性能设计和性能目标,基于最佳实践进行开发,并通过用例测试进行动态分析,给出更充实的优化方案和建议。
测试验证阶段,由于性能指标和代码实现已经齐备,可以通过在测试环境的持续监控和仿真测试来对系统性能进行评估。
运营维护阶段,通过观测手段对生产系统进行分析和剖析,产出性能变化趋势和优化建议,真实环境的场景和数据沉淀后形成知识。
版本迭代阶段,基于设计目标和实际分析结果,建立性能基线,用于新版本发布前的性能看护,以快速识别劣化点。
上述全流程方法,从设计规划阶段开始关注性能,到运营阶段完成分析和看护,能形成性能工程的持续反馈闭环,也能实现研发性能左移。
固化专家经验形成知识库,沉淀性能优化标准实践
通过持续的指标检测,形成性能指标数据库,将积累的性能指标在不同系统之间关联,能够从趋势上洞悉业务变化从而以数据驱动架构设计决策。
对日常性能分析和优化的实践经验进行总结提炼,形成特定场景的性能分析流程、性能劣化反模式,以及性能优化思路,固化进知识库以供参考。知识库使业务研发人员也能基于标准化流程尝试解决性能问题,这极大地降低了性能专家的工作量,使其能更专注于少量疑难杂症的解决。
形成一定规模的知识库后,一方面能够基于知识沉淀出方法,进而研发出公共平台组件一劳永逸的解决同类问题。另一方面能够通过机器学习的手段,对发现的性能问题给出解决方法建议和步骤,进一步降低性能优化的难度。
自助化性能分析,降低工具学习和使用成本
通过构建平台化的性能工程能力,为研发人员提供一站式的性能分析工具集和自助式使用体验。在该场景中,研发团队扮演需求提出方,平台团队扮演能力提供方。
通过建设可观测体系,平台可为研发团队提供开箱即用的监控能力市场,常见的如 APM、全链路观测等,实现对系统各类性能指标的一键监控。
通过封装各类性能分析工具集,以帮助研发团队通过简单的操作就可以对不同环境下运行的各类异构应用、中间件、系统甚至硬件进行数据采集和即时分析,并生成可视化友好的分析报告,如火焰图、调用图、内存地图、请求分析图、线程分析图等。
通过扩展持续交付流水线,允许研发团队将各类性能指标和测试用例在流水线上集成和关联,以方便形成性能基线,并为性能看护提供基础设施和流程自动化的支持,以实现持续的性能改善,防止性能劣化。
如何开始?
本文先讨论了性能问题日趋严峻且不容忽视,之后引出了研发团队在处理性能问题时的现状问题和挑战,然后对应每一种问题,提出了性能工程的实现目标。
那么,如何才能开始建设性能工程体系?企业落地性能工程的实践有哪些?怎样评价企业性能工程建设的水平?
请看后续系列文章。
免责声明:本文内容仅表明作者本人观点,并不代表Thoughtworks的立场