Performance
Otimização
Engenharia de Software
Observabilidade
Boas Práticas

软件性能:开始优化的基本步骤

优化性能是有顺序的。跳过诊断是最常见也是最昂贵的错误。

当应用程序速度变慢时,大多数团队的本能是开始修补。更改库、添加缓存、升级更大的机器。这是错误的反应,而且代价高昂,因为它在了解疾病之前就先攻击症状。

表演是有方法的。步骤的顺序是正确的,并且早在您接触一行代码之前就开始了。本文适合那些已经了解自己需要优化并希望知道从哪里开始以严格的方式开始,而不是在错误的地方浪费数周时间的人。

我不会将其视为技巧列表。技巧解决特定情况并且很快就会过时。方法可以解决任何情况并维持自身。

步骤 0:定义“快”的含义

首先回答:什么是可以接受的? “系统速度慢”不是一个可操作的问题。 “列表页面需要在不到一秒的时间内响应 95% 的请求”。

没有目标,你永远不知道什么时候停止。没有目标的优化是一个无底洞,你总是可以让它变得更快,但总是付出更多的努力却收获更少。定义可接受的响应时间限制(最好按百分位数)将分散的感觉转化为客观标准。

这一步看起来很官僚,但正是它将优化工作与无休止的搜索区分开来。这既是一场产品和业务对话,也是一场工程对话:什么是“足够快”取决于用户想要做什么。

第 1 步:移动前测量

整个学科最重要的规则是:你不能优化你不衡量的东西。如果没有仪器,任何改变都只是猜测,而且猜测完全靠运气。

使用指标、结构化日志以及理想情况下的分布式跟踪来检测应用程序。目标是回答一个简单的问题:时间都花在哪里了?答案几乎总是令人惊讶。瓶颈很少出现在直觉指出的地方。

重复出现的模式:团队发誓问题出在语言或框架、工具上,并发现 80% 的时间都在单个数据库查询中。如果不进行测量,该团队将重写整个应用程序,但问题仍然存在。

工具比习惯更重要。它可以是一个完整的[可观测性0解决方案或一个放置得当的日志。不能缺少的就是数据。

步骤 2:首先解决最大的瓶颈

掌握了数据后,优先级就变得显而易见。有一条强有力的经验法则:大多数经济放缓往往是由少数原因造成的。首先攻击最大的一个。

抵制住进行十项微优化的诱惑,这些优化加起来没什么用处。找到单独占用最大时间的项目并解决它。消除主要瓶颈所带来的收益通常大于所有其他改进的总和。

求出最大后,再次测量。瓶颈移动了。第二大现在是新目标。绩效是一个测量、纠正和补救的迭代过程,而不是单一的努力。

第三步:从数据库开始

在大多数业务应用中,银行业务是浪费时间最多的地方。这就是为什么它值得优先关注。三项检查可以解决很大一部分问题:

  • 缺少索引。 由于筛选列上缺少索引而扫描整个表的查询。这是最常见的错误,也是最便宜的修复方法。
  • N+1 问题。 当代码对列表进行查询,然后对列表中的每个项目进行附加查询时。一百个项目看到了一百零一个查询。通过一次性加载相关数据即可解决。
  • 带来太多数据的查询。 使用三列搜索整个表是对数据库、网络和内存的浪费。

仅这三个修复就改变了许多系统的速度感知。而且它们都不需要改变技术。

步骤 4:明智地使用缓存

缓存是最诱人也是最危险的优化。它带来了立竿见影的收益,并引入了一整类新的错误:过时的数据。

黄金法则:只卷曲可能稍微旧的东西,而不会造成损坏。并且始终明确定义缓存将如何失效。没有失效策略的缓存不是优化,而是一颗定时炸弹。

对于敏感数据、余额、订单状态、发生变化且其准确性很重要的信息,请三思而后行。在处理金钱或公民决策的系统中,数据的正确性胜过速度。更快地显示错误号码对任何人都没有帮助。

还值得记住的是,缓存存在于多个层中:用户的浏览器中、中间层中、服务器上、银行中。每个解决不同的问题并有其自己的失效成本。初学者的错误是在不了解哪个缓存响应什么的情况下堆叠缓存,然后,当一条数据出错时,没有人知道它卡在哪一层。有意识地映射缓存操作的位置是充分利用缓存的一部分。

步骤 5:然后才考虑基础设施

升级更大的机器或添加更多实例通常是团队采取的第一步。它应该是最后之一。

在不首先修复代码和银行瓶颈的情况下扩展基础设施就是在花钱解决问题。你付出更多的代价来完成同样低效的工作,只是并行的。成本增加,效率低下仍然存在,而且现在更加昂贵。

当代码优化已经完成并且真正的限制是容量时,然后基础设施就进来了。正确的方法几乎总是水平扩展,添加实例,这要求应用程序是无状态的。这是一个值得尽早做出的架构决策,因为以后修复它是很费力的。

导致所有步骤无效的错误

有一个文化缺陷会破坏任何脚本:凭直觉优化并庆祝而不衡量结果。团队改变了一些东西,感觉它变得更快并且继续前进。如果在改变后没有进行测量,你不知道它是变得更好、更糟还是什么都没有发生。

每次优化之前和之后都需要可衡量的。否则你只是在移动代码并扭曲。

诚实的反思:大多数性能问题不需要天才或昂贵的工具。它需要纪律。衡量、确定优先级、解决最大瓶颈并进行补救。遵循此顺序的团队在几天内就能解决那些猜测的团队在几个月内无法解决的问题。

出色的绩效不在于天赋,而在于过程。那些将这些步骤内化的人将停止灭火并开始预防火灾。

如果你的团队一直在黑暗中解决缓慢问题,也许问题不是技术上的,而是方法上的。博客上还有其他关于质量、[可观察性1] 和可扩展性的文章,对这个路线图进行了补充。如果您想就如何在组织中构建这一点交换想法,那么值得讨论。

另请阅读

  • 【移动端性能优化:让应用飞起来的必备步骤2
  • [软件性能:关于质量的真实案例教学3
  • 【应用中的电池消耗:如何优化移动性能4
  • [Web 应用程序中的延迟 - 实施基本步骤5
  • [软件质量指标:验证和基本步骤6
  • [自动化测试:为什么未经测试的代码是债务7