写点什么

软件动力学

作者:agnostic
  • 2023-02-05
    上海
  • 本文字数:2610 字

    阅读完需:约 9 分钟

通常的软件相关的理论,不论是关于工程理论的 XP、Scrum、RUP、TOGAF,还是关于方法论的 OO、DDD、TDD、CDC,或者关于技巧的设计模式、Restful 等等,都是一种静态的理论,指导的一次软件工程、软件设计的实践。但是,除了 IT 咨询、IT 外包之外,大部分的软件都是一个比较长的生命周期,都有一个演进、维护的过程。这些静态的理论,往往不能很好的知道软件的生长。


关于成长的理论,最有名的其实是《物种起源》,也就是进化论。最近,看到 thoughtworks 在 19 年左右提出的「演进式架构」,似乎是我们需要找的答案,我暂时给这类的方法论起一个总的术语:软件动力学。和机械动力学一样,是研究软件在发展过程中的理论。


在展开论述之前,先简单介绍一下《演进式架构》的核心观点。总结下来,thoughtworks 的可演进架构理论主要就是三点:

  1. 用适应度函数来评判架构演进的方向和质量。

  2. 采用增量变更的方式实施架构演进。

  3. 架构之间必然存在适度的耦合,提出了架构量子的概念:系统最小的可部署单元(代码+数据...)。架构量子越小,架构的演进能力越强。通过这个来评判架构的可演进性。所以,架构可演进性:Faas>微服务>SOA>模块化单体>分层单体>普通单体架构。


总觉得有点味道,但还不是那么完整。我说一下我对软件演进的理解。要理解软件演进的过程,首先我们需要从长周期和短周期的维度去分析。


和进化论一样,在相当长的时间跨度上,所有的物种的解决都应该是灭绝。所以,

原则 1:所有的软件和服务都应该有它的生命周期,不要进行无限度的维护。

这里面有两层意思。

首先,所有的系统和应用都应该有适合他生存的环境。我们可以通过组织、业务和技术的维度去评估一个系统是否适合继续维护。如果答案是否定的,我们应该果断的进行系统的下线。不合适的场景可能包括:

  • 组织的巨大变化,根据康威定律,系统架构已经完全不符合组织的沟通结构。

  • 业务的巨大变化,系统提供的服务已经完全无法满足新业务的诉求。

  • 技术生态的巨大变化,系统对应的基础架构已经不符合技术演进的要求。

这就好比恐龙,改灭绝就应该灭绝。人为的创造一个小生境去维持一个过时的物种,除了观赏价值外,在生物学上是没有任何价值的。

其次,对于系统内部的服务,也应该有一个明确的生命周期。 

我们在实施服务升级的时候,需要兼容老的服务版本。这个在商业化的角度是必须的。但是兼容是有巨大的成本的,兼容的版本越多,系统的历史负担就越大。所以,对于一个系统,兼容的大版本最好不要超过个位数。这就要求对于老的服务,需要规划合理的下线过程。对于老服务的历史数据,也需要迁移到新模型。


其次,我们知道越简单的生物,例如细菌、病毒,他们的生命力越强。所以,

原则 2:强耦合的部分越小,软件的生命力越强。

这个和「演进式架构」中提出的观点是一致的,我们可以通过架构量子来评判一个系统的可演进性。在我们做架构设计的时候,需要严格控制系统的覆盖范围,不要做一个大而全的“泥球”系统,或者在一个大的技术团队内部用单体架构来构建系统。

系统和系统之间,如果没有耦合的必要,就不要有任何的依赖。

如果有相互的依赖关系,就用服务契约这个唯一的语言将系统和系统之间串联起来。


还是和进化论一样,对于软件生命力的评判,需要通过客观的标准,而不是由 CTO 来主观决策。所以,

原则 3:为软件架构的各个维度定义适应性函数,通过适应性函数来评判演进的合理性。

适应性函数(Fitness Function),是对于一类架构维度的评判(打分)标准。

对于功能性部分,这个可以是相应的测试用例,包括单元测试、契约测试、功能测试和用户验收测试等。

对于非功能性部分,这个适应性函数就有可能是 SLA,比如:

  • 对于容量,是压测的指标。

  • 对于性能,是相应的 RT。

  • 可用性的指标。

  • 容灾的 RPO 和 RTO。

  • 安全性的一些规则。

  • 合规的条款符合度。

  • ……

适应性函数,会是一个庞大的集合。所以需要适应性函数的运行(回归)是一个自动化的过程。


自然环境中基因突变,往往是很小一段基因的改变。对于个体也是微弱的影响,比如在某个特征上有小幅度的变化。然后在不停的适应强化过程中,去判断是进化还是退化,逐步进行自然选择。大的突变,往往就是遗传疾病,是没有生命力的。所以,

原则 4:小步快走,通过增量的方式进行架构演进。

在我们架构设计的过程中,最好也采用小步快走的方式。这里面的原因有三:

  1. 架构的演进是需要资源投入的,同时架构演进不一定会是成功的,所以我们需要尽快的去完成并进行评判,不要过度的浪费资源。

  2. 如果一次迭代的内容过多,适应性函数的判断如果是负面的,容易误杀其中有价值的架构演进部分。

  3. 多个架构演进可能并发展开的,过大的架构演进会阻碍相关架构演进的执行。

小步,是我们操作上面的指引。快走,要求自动化。


在架构演进的过程中,势必会有新老架构(服务)并存的场景。在并存时期,我们需要考虑前后的兼容性。根据前面生命周期的原理,我们也需要考虑老往新的迁移。

原则 5:软件架构演进的最佳实践,包括兼容性和数据迁移。

第一,考虑服务兼容性。因为我们存在系统之间相互调用的关系。所以新设计的架构需要能处理老服务的流量。最简单的就是通过增加一个适配层来兼容。但是也不能无限兼容,我们不可能在系统中保存十几个服务版本。所以对于老的服务需要有一个逐步下线的过程。包括历史服务存续期的规范、下线的通知机制、历史流量的监控机制。对于服务兼容性,我们有相应的测试能力进行保障,契约测试就是一个很好的方式。

第二,需要考虑到遗留数据的处理。对于遗留数据,又可以分为两类数据。一类是交易过程中的临时数据,生命周期随着交易结束就结束了。比如议价过程、意向单据等。一类是长期的数据,在交易结束后还会长期保存并被查询。比如账单、交易订单等。对于第一类单据,不需要做数据迁移,虽然有的单据可能存续的时间比较长,比如意向单会存在三个月到半年。这无非就要求新旧的产品在三个月到半年时间并存罢了。对于第二类单据,是需要考虑进行数据迁移。对于有停机窗口的系统,可以通过离线 ETL 的方式将数据从老模型迁移到新模型。对于没有停机窗口的系统,对历史单据查询需要增加双读的方式,保证在数据迁移过程中也能提供查询能力。同时,为了支撑数据迁移,在做数据模型设计的时候,要充分理解业务,对于一些业务上目前说不清楚的信息,尽量能先预置到模型中,这样在模型升级的过程中可以尽量避免信息丢失的情况。


最后,演进可能进化也可能退化。所以,

原则 6:在架构演进的过程中需要充分考虑到系统稳定性。不要进行全量演进,要有灰度的过程。

发布于: 刚刚阅读数: 4
用户头像

agnostic

关注

常识、KISS、高可用、合规架构、架构治理 2019-02-14 加入

二十年架构经验,互联网金融专业架构师。Open Group Master Certified Architect

评论

发布
暂无评论
软件动力学_可演进架构_agnostic_InfoQ写作社区