1

“分布式” 开发规范治理

 2 years ago
source link: https://www.phodal.com/blog/distributed-guard/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Posted by: Phodal Huang March 7, 2022, 8:10 p.m.

PS:本文只是先开个头,思考如何应对这种挑战。

如果只是从系统来考虑,标题里虽然说的是 “分布式” 规范治理,但是更多的时候是指多仓库的规范治理。而多仓库本身也充斥着一些不合理性,诸如于一个代码仓库内,可能包含着多个模块,如 monorepo。从这个角度来看,只是讨论分布式系统,可能有一些单薄。但是呢,我们在写规范,针对的是系统吗?难道不是团队中的开发人员?所以,我们所想的治理的是分布式协作的规范性问题。

回顾开发规范及其工具化

对于软件研发来说,效能的提升是一个非常宏大的史诗级话题,在这个话题里,规范的建立是一个非常有效的方案 —— 当且仅当,我们建立了配套的相关执行机制和工具。在确保了拥有统一规范的情况下,A 团队的开发人员,可以快速地到 B 团队开发,而不需要一些额外的讨论。简单来说,规范就是一种用于规模化提升效能的模式

多年前,对于软件开发的规范,我们主要依赖于口头约定 + code review,这依赖于团队拥有比较好的技术能力。应对于规模化时,这样的模式是无法实施的。特别是开发团队质量不齐的情况下,依附于个人的自觉,已经难于控制团队的质量。特别是,我们会因为越来越多的 quick fix,导致一次又一次性破坏系统的规范。

人们开发了一系列的 Lint、Checkstyle、守护工具,以确保我们设计的规范能被实施下去。诸如于:

  • 针对于前端,我们有 ESLint、Prettier
  • 针对于后端,我们也有一系列的工具,如:PMD/CheckStyle。还有国内流行的阿里、华为 Java 规范。
  • 针对于 Java 架构,我们有:ArchUnit
  • 针对于 API,我们有:API Linter、Spectral
  • 针对于数据库,我们有:SQLFluff

于是,在单体系统里,上述的一系列情况得到了有效的改善,但是我们来到了微服务时代、微前端时代等,整体又发现了一系列的变化。为了应对于这种变化,我们还需要一些额外的工具,以确保这些规范化的工具能被安装和使用。

在那之前,让我们先总结一下规范工具化的时机,以明确我们应该在哪个时机来应对分布式下的挑战。

规范工具化的时机

从模式上来说,我们通常会在如下的一些时机里,来检查软件是否符合规范。(按顺序排序)

  • 创建态。即将规范内嵌到每个应用的创建模板中。典型的形式是应用脚手架 等。
  • 开发态。即结合开发过程中的工具(如 IDE、Git、CLI),将规范内置到开发流程中。典型的有 Git Hooks、IDE 插件等。
  • 测试态。即结合自动化测试、契约测试等,在运行测试的时机,检查已有的系统是否遵循相关的规范。
  • 集成态。即对于规范的检查配置在持续集成中,有时会作为一种强制的软件质量门禁。典型的有 SonarQube 等。
  • 运行态。即结合软件运行的信息(如 APM、日志、分布式链路系统等),对系统进行系统进行分析。典型的有 NewRelic、Skywalking 等。

从执行顺序来时机来说,越往前便意料着越能及早的发现错误,成本也越低。当然了,每种不同的时期,都应该有各自的重点。

时机 关注点 工具示例

创建态 代码规范内建、规范执行机制、分层规范等 应用脚手架

开发态 代码规范 CheckStyle 的 Intellij IDEA插件

测试态 代码规范、分层架构、API 规范等 ArchUnit

集成态 质量门禁 Sonarqube

运行态 服务依赖 Skywalking

当然了,还有一些是跨越了多个不同的时机,诸如于契约测试,它是在开发时期定义的,但是可能会在测试态、集成态才验证的。然而,在过程中,很大一部分的内容都是在代码中,由开发人员控制的。作为一个开发者,也是一个 hacker,我们会习惯性的:

  1. 跳过不需要的自动化检查。
  2. 路过不需要的测试。它可能跑起来很慢
  3. 删除或者禁用一些不需要的规范代码或者配置。

这样一来,哪怕我们做了再好的规范设计,代码不,没有 code review 的保障,那么系统就会被进一步地腐化。

分布式场景下的规范

现在,让我们回到先前我们定义的分布式场景,思考一下如何在这种场景下,构建规范工具化?

分布式的规范工具化

对于这些规范来说,它们的工具化思路类似于,我们在《代码分析与自动化重构》所说的:源码分析 → 构建模型 → 识别模式 → 得到结果。为了支撑到分布式场景,一些潜在的方案便是:

  • 工具化代码块。使用额外的代码模块(如 Git Submodule、软件包等)来执行规范的自动化,诸如于 npm 包、jar 包的形式。
  • 工具检查器。检查是否安装了对应的工具,是否执行了对应的步骤。(并不推荐)
  • 构建新的工具。如 Guarding 这种模式。
  • 设计成熟度指标。用于指导和改善系统的架构设计。

去年,在设计 Guarding 这个多语言的架构守护工具时,其与 ArchUnit 相比的场景是:多语言、多代码库。与 ArchUnit 相比,Guarding 推荐的这种守护方式是:

  • 以 CLI 的方式运行。无需额外的编码工作,不担心系统被破坏。
  • 配置在持续集成中。
  • 多系统多语言守护。

当然了,它更多的是在测试态、开发态来解决问题。理想情况下,应该包含 IDE 插件,在开发时能提醒开发人员,系统架构有哪些问题。

指标模型:架构适应度函数

虽然,我们可以构建一个基于“分布式”场景的规范,但是从某种意义上来说,这些规范是一种约束。对于开发人员来说,我们需要一种更好的指导指标,而不是我们破坏了哪些规则。所以,我们应该考虑架构适应度函数的方式,从多个不同的维度,来帮助开发人员:

  1. 理解系统的当前状态
  2. 理解指标对于系统的意义
  3. 指导系统更好的演进
  4. 知悉什么是好的模式和设计

也因此,从这个层面来考虑,单体系统里的 Sonarqube 就是一个非常好的工具。

最后,回到我们所推崇的敏捷实践,个体和互动高于流程和工具。让架构和系统知识能在团队中流动起来,远远比工具更加重要。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK