每个团队都经历过这样的场景。该产品在演示中运行良好,通过了测试,令客户满意。三个月后,随着实际流量的增加,应用程序开始出现阻塞。页面需要时间。支持充满了抱怨。而且没有人确切知道问题出在哪里。
性能很少会突然崩溃。它逐渐退化,隐藏在当系统有一百个用户时看起来很舒服的指标后面,而当系统有十万个用户时就变得不可持续。危险不是明显的峰值,而是无声的侵蚀。
我想用这篇文章来了解绩效的真正含义:对现金流、声誉和增长能力产生直接影响的质量决策。不是“优化代码”的问题,而是工程成熟度的症状。
性能是品质,不是装饰
有一种懒惰的文化将“使其发挥作用”与“快速完成”分开,好像第二个步骤是以后的可选步骤。这种分离是错误的。缓慢的系统是一个有故障的系统,只是故障表现为用户放弃,而不是错误屏幕。
我捍卫的论点很简单:性能是一种非功能性需求,需要像功能性需求一样严格对待。如果您对“就绪”的定义不包括负载下的行为,则您对就绪的定义是不完整的。
我在数字政府产品中痛苦地看到了这一点。公共服务门户可能在技术上是正确的,但在注册或申报截止日期开放当天仍然会失败。在那一天,高峰访问是规则,而不是例外。而正是在这一天,公民的信任得到或失去。
情况 1:瓶颈在银行,而不是在代码中
一个团队花了数周时间重写应用程序层,并确信问题出在语言上。他们改变了库,重构了功能,与框架进行了斗争。延迟下降了一点。
当他们最终对查询进行检测时,真相浮出水面:没有索引的单个查询正在使用每个请求扫描整个表。问题从来都不是应用程序。这是著名的 N+1 变相的结果,乘以每月都在增长的清单上的每一项。
课程不是技术性的,而是文化性的。你猜,如果没有**[可观察性0**、指标、跟踪、结构化日志,你就无法优化。而且猜测的成本很高。该团队在错误的地方花了数周时间,因为他们无法了解时间实际消耗在哪里。
规则仍然是:移动前先测量。没有测量的优化是迷信。
情况 2:撒谎的缓存
另一种产品通过积极的缓存解决了您的负载问题。它运行得很好,直到数据开始变得过时。用户看到旧的余额、已经改变的状态以及与现实不符的信息。
性能的提高是以牺牲正确性为代价的。在处理金钱或公民决策的系统中,正确性是不容谈判的。
这里的学习是关于明确的权衡。缓存是最强大的工具之一,但每个缓存都是一场赌博,数据可能会稍微陈旧。这个赌注需要是一个有意识的、记录在案的决定,具有明确的失效策略,而不是在压力下应用的补丁。
常见的错误是将缓存视为魔法。当团队不确切了解缓存的内容、缓存的时间和原因时,缓存就不再是一种优化,而是成为难以重现的错误的来源。
案例 3:系统垂直扩展直至无法运行
成长型公司有一个经典模式:流量增加,答案就是租用更大的机器。它有效一次、两次、三次。直到有一天没有更大的机器,或者它的成本贵得离谱。
我跟踪的一个案例正是有这个限制。该系统是整体的,状态存储在本地内存中,这阻止了多个实例并行运行。水平扩展需要重写应用程序保存会话的方式。
这次纠正并不英勇。它正在外部化状态,使应用程序真正无状态,并将平衡器放在前面。从那时起,增长就变成了添加实例的问题,云基础设施几乎自动解决了这个问题。
战略愿景:架构早在代码之前就设定了增长天花板。当产品规模较小时,早期做出的决策决定了产品规模较大时扩展的成本。
这些案例有什么共同点
这些问题本质上都不是语言或框架问题。所有这些都是诊断、权衡和架构的问题。成熟的团队并不是编写最快代码的团队,而是了解时间花在哪里并深思熟虑地决定在哪里投入精力的团队。
这三种情况贯穿三个原则:
- 优化前先测量。 如果没有数据,您就修复了错误的地方。
- **权衡需要明确。**每次优化都会用一件事交换另一件事。知道你在交换什么。
- 架构决定命运。 扩展成本由结构决策决定,而不是由实施细节决定。
过早和晚期优化的陷阱
工程学中有一句众所周知的说法,过早的优化是万恶之源。确实是这样,但已经成为借口了。团队使用这句话来忽略性能,直到问题爆发到生产中。
正确的点是在中间。不要优化没有人使用的东西。但要尽早设定可接受的响应时间限制并对其进行衡量。您不需要优化所有内容,您需要知道某些内容何时超出了不可接受的范围。
诚实的批判性反思是:大多数性能灾难并非源于缺乏技术知识。它来自缺乏可见性和文化。不进行测量、不谈论预期负载、不检查最繁重的查询的团队将重复相同的错误,无论他们使用什么堆栈。
性能作为业务优势
对于那些领导者来说,扭转逻辑是值得的。性能不是工程成本,而是业务杠杆。快速的产品可以带来更多的转化、更多的留存以及更低的运营成本。无需重写即可扩展的系统可以让团队自由地进行构建,而不是救火。
在公共部门,争论更加直接:能够处理高峰需求的数字服务就是履行其功能的服务。在最重要的日子发生的事情会摧毁多年来建立的信任。
最终,软件质量是许多认真对待的小决策的总和。性能是最明显的因素之一,也是区分成长型产品与仅仅生存型产品的最大区别之一。
如果您的组织正在经历性能下降而不了解原因,那么第一步几乎永远不会改变技术,而是获得可见性。博客上还有其他关于质量、架构和可扩展性的文章,深入探讨了这条道路。如果这是一个让你彻夜难眠的问题,那么就值得讨论一下。
另请阅读
- [应用程序中的微服务:小型团队的用例1
- [单体与微服务:实践中的用例2
- [软件性能:开始优化的基本步骤3
- 【软件测试周期:早测试者(和晚测试者)的趋势和真实案例4
- 【应用中的电池消耗:与真实案例的比较5
- 【GraphQL应用:真实案例的成本与定价6