构建更优软件架构的三个关键问题

本文探讨了在最小可行产品开发过程中,团队需要按顺序回答的三个关键架构问题:业务价值验证、性能与可扩展性需求、可维护性与可支持性要求,帮助团队做出更明智的架构决策。

关键要点

  • 最昂贵的决策,也是需要首先考虑的,是构建一个不值得构建的产品
  • 如果产品值得构建,下一个最昂贵的决策是构建无法充分执行或扩展以满足其业务案例的东西
  • 一旦这些问题得到满足,下一个最重要的决策就与生命周期成本相关——这些选择使系统在其生命周期内可维护和可支持
  • 当新信息可用时(由于发生的事件),重新审视决策和权衡,以评估是否违反了某些关键假设或必要条件
  • 实验不能告诉你哪些决策是正确的,但可以告诉你哪些决策是错误的

在任何软件开发工作中,总是有太多事情要做,而没有足够的时间或资源来完成所有事情。问题在于我们可以构建的东西数量是无限大的,而我们可用的时间和资源相比之下几乎是无限小的。

这尤其适用于架构设计。软件架构设计的艺术在于决定现在需要做出哪些决策,哪些可以等待。

做出决策涉及回答关键问题,而某些问题需要按特定顺序回答。成功的架构设计涉及使用经验主义快速且廉价地拒绝错误的假设/断言。换句话说,快速找到那些错误且成本高昂的替代方案,并选择更好的替代方案。最小可行产品(MVP)及其最小可行架构(MVA)方法有助于回答这些问题。

当面临在感觉不切实际的截止日期前交付MVP的挑战时,团队需要按特定顺序回答几个关键问题:

  1. 商业理念是否值得追求?
  2. 需要多少性能和可扩展性?
  3. 需要多少可维护性/模块化和可支持性?

图1:3个关键问题的答案决定了MVA决策和权衡

这些问题的答案决定了团队在设计MVA时需要做出的架构决策和权衡(见图1)。

这个列表不包括关于安全性(包括网络安全和数据保护)的问题,因为安全性是不可协商的,因此不应涉及权衡。正如我们在之前的文章中讨论的那样,回答这些问题的唯一方法是使用经验主义并进行实验。

最重要的问题是"商业理念是否值得追求?"

想法是廉价的,解决方案是昂贵的,而不解决有用问题的解决方案只是浪费。团队可以做出的最重要的决定是决定不构建人们不需要的东西。MVP测试提议解决方案的价值。对我们来说,MVP是确定产品理念是否有价值的一种机制。

MVP必须测试在提出业务理念供批准时做出的假设(尤其是技术假设)。这些假设是否仍然有效?你怎么知道?你需要收集什么数据来决定?MVP需要被设计来收集这些数据。

这与软件架构有什么关系?你不想为一个没有人需要的产品创建架构。在验证业务理念时,你将测试驱动质量属性(如可扩展性和性能需求)的假设。要做到这一点,MVP必须不仅仅是一个概念验证——它需要能够足够好地扩展和执行以验证业务案例,但它还不需要回答所有关于可扩展性和性能的问题。

此外,成本始终是一个因素,MVP必须评估是否能够满足业务案例。如果解决方案太昂贵而无法满足用户需求,就不值得追求。MVA需要探索足够多的成本问题,以确保解决方案不会超出预算。

第二个最重要的问题是"性能和可扩展性如何?"

早期的性能问题是未来扩展问题的领先指标,业务赞助者至少隐式地理解这一点。如果一个系统在只有一个或几个用户时显示响应时间慢,业务赞助者会质疑该系统是否能够满足其性能和扩展目标。因此,早期关注性能可以保障开发工作的未来。

做出与性能相关的决策的挑战在于"性能"是主观的,取决于用户的期望。他们当然希望系统即时响应,但他们愿意接受小的延迟。因此,团队有机会在处理方式上进行权衡。例如,耗时较长的任务可能会移到异步后台任务中,而用户正在做其他事情,只要结果在用户需要时准备好即可。

用户也会根据性能预测可扩展性。糟糕的初始性能可能会让用户怀疑系统是否能够扩展并提供可接受的性能。这可能会导致对MVP可行性的质疑。

在处理性能问题时,有一些类似于物理定律的确定性:

  • 由于物理吞吐量限制,从存储设备访问数据总是昂贵的
  • 由于延迟限制,远程数据访问非常非常昂贵
  • 可以通过将数据移动到内存来降低数据访问成本,但这只有在数据量小且内存相对较大时才有效

因此,数据驻留位置和访问方式总是存在权衡,因此在两个处理成本来源之间存在权衡。

你怎么知道?你需要收集什么指标来决定?

有时执行复杂算法需要很长时间,是性能问题的根源。除了优化和近似之外,这些计算通常很适合移到后台任务中。

验证系统是否表现良好需要团队构建系统的关键部分,以便测试关于某些事情需要多长时间的假设。团队不需要构建整个系统,但他们确实需要构建对性能影响最大的系统部分。

与性能相关的问题是"需要多少可扩展性?"

可扩展性是一种无形的质量,通过在大负载(用户、数据、事务等)下表现不佳而显现出来。因此,衡量可扩展性需要团队在负载增加时衡量性能。用户希望系统在扩展时具有良好的性能;对他们来说,增加负载应该是"无形的"。

投资可扩展性是团队将做出的最昂贵的决策之一,因为通常没有限制他们可以做什么来改善可扩展性。问题是知道他们实际需要多少可扩展性。

致力于交付MVP的团队几乎总是面临可扩展性挑战。他们应该现在设计可扩展性还是推迟该决策?正如我们在之前的文章中讨论的那样,扩展系统是一个难以解决的问题。找到正确的平衡至关重要。在可扩展性方面投资不足会限制系统的寿命,而过度投资会由于成本而对MVP的业务案例产生负面影响。

团队常常难以准确预测可扩展性需求,部分原因是业务赞助者可能难以预测系统使用增长;业务赞助者通常希望近乎"无限"的可扩展性,不幸的是,没有相应的预算。然而,可扩展性要求始终存在;它们只是不总是显而易见的。每个系统都有一个业务案例,在该案例中,有隐式的可扩展性需求。

最终,实现负担得起的可扩展性需要做出谨慎的权衡。例如,通过使某些任务异步可以提高可扩展性,但这样做会增加协调这些后台任务的复杂性。这种复杂性不是免费的,可能会影响性能。

在扩展时实现良好性能也可能意味着重新构建你已经构建的部分解决方案;在少数用户下表现良好的解决方案可能会在负载增加时崩溃。另一方面,你可能永远不需要扩展到导致这些故障的负载,因此过早过度投资可能只是浪费精力。

许多扩展问题也源于关键瓶颈,通常与访问共享资源有关。及早发现这些可以告知团队何时以及在什么条件下可能需要改变他们的方法。

第三个重要问题是"需要多少可维护性/模块化和可支持性?"

团队以模块化方式开发他们的系统,以使其更易于开发、理解和维护。更模块化的系统也有助于团队识别和利用重用机会。其他技术,如参数化或可配置性,使系统更易于维护,因为某些类型的更改不需要代码更改。

然而,这些策略的有用性是有限的。预测永远不会发生的变化只是浪费精力。启用从未使用过的可配置性也是浪费。在你不知道MVP是否会成功之前,你为使系统更加模块化、可维护和可支持所做的努力可能只是浪费。

使系统更可维护和可支持的挑战在于预测最可能发生的变化类型,并在代码中为变化做准备。

在之前的文章中,我们确定了开发MVP及其相关MVA时的5种可能结果:

  1. MVP成功,MVA不需要改变
  2. MVP成功但MVA不可持续
  3. MVP部分成功但不完全成功,但可以修复
  4. MVA也部分成功但不完全成功,需要改进
  5. MVP不成功,因此MVA无关紧要

在那篇文章中,我们观察到结果#2、#3和#4是团队最可能处理的情况。如果MVP成功,团队应快速确定MVA是否可持续。这使得大多数团队处理结果#3和#4。

在情况#3中,团队应该投资足够的可维护性来帮助他们修复MVP,因为他们还不知道MVP需要做什么。总是存在风险,他们对MVP进行一些更改,然后发现他们实际上在处理结果#5,一个不可行的MVP。实际上,这意味着投资构建足够的模块化以使他们的下一次迭代更容易,例如,通过定义主要组件的接口,但仅构建足够的实现来支持MVP;细化可以留待以后。

情况#4更简单但也更复杂;MVP可能需要更多工作,但MVA肯定需要更多工作。换句话说,你还没有可行的MVA。例如,它可能表现不佳或无法扩展。或者它可能缺少你不知道是否需要构建的主要组件,如果你需要构建它们,它们将花费太多。在这种情况下,团队的重点当然应该是证明MVP,但也要探索可能的MVA权衡,以确定是否存在满足MVP需求且负担得起的MVA。

这与模块化、可维护性和可支持性的关系是,团队应该投资足够多,以便在他们需要的时间内继续发展MVA。有时在模块化和性能/可扩展性之间存在权衡,因此需要通过运行实验来检查这些权衡。

使用技术债务评估可支持性和可维护性

正如我们在之前的文章中讨论的那样,技术债务是一种流行的隐喻,用于向利益相关者传达架构决策和权衡的长期影响。技术债务是衡量系统可支持性和可维护性的一种方式。由于需要快速反馈业务概念和支持它的技术解决方案,在交付MVP时产生技术债务是不可避免的。

团队必须做出的最重要的架构决策之一是决定他们将如何知道技术债务已经上升到系统将来无法支持和维护的程度。他们需要知道的第一件事是他们实际产生了多少技术债务。他们可以做到这一点的一种方法是在他们的架构决策记录(ADR)中记录产生技术债务的决策。

他们需要做的下一件事是使用经验主义来测试可维护性和可支持性。一种方法是在团队发布版本时考虑返工的成本。在每次迭代中(例如,使用Scrum的Sprint),团队在根据先前迭代的反馈合并学习时不可避免地会产生一些返工。衡量这种返工可以帮助团队理解撤销/重做现有代码的成本。

理解可维护性和可支持性的另一种方法是将变更案例纳入工作。变更案例非常简单,是一些故意的返工,测试架构决策在代码中更改的容易程度。它可能涉及切换主要组件或子系统,或在某些区域将消息传递模型从同步更改为异步。关键是通过在代码的一小部分进行该更改,然后推断结果以评估可维护性,来预测未来可能发生的变化。

结论

套用老毛奇的话,没有MVP能在与客户接触后幸存。这也会波及整个MVA。在架构决策方面,团队需要首先考虑业务理念是否值得追求,如图1所示。这反过来会改变他们关于MVA的决策。

根据我们的经验,团队必须做出的下一个最重要的架构决策集涉及性能和可扩展性,因为这些影响广泛的技术选择。只有这样,关于可维护性和可支持性的决策才值得考虑,因为性能和扩展决策的变化通常会影响系统的组成。反过来,这些决策可能通过超出成本约束来影响系统的业务可行性。

架构决策的一个挑战是它们从未真正一劳永逸地决定;每个新信息都可能改变决策的影响,因此团队总是在适应新情况调整他们的决策。因为MVP是一系列小实验,它将基于反馈随时间演变。MVA也需要以类似的方式和时间框架演变。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计