阅读:49
架构工作台是一个环境,其设计初衷用于帮助人们设计架构、演进架构、观测架构,并有效地运用架构所需要的高质量工具,如交互式的架构开发和分析。
在上一篇文章《架构即代码:编码下一代企业(应用)架构体系》中,我们介绍了架构即代码的思想,它是如何围绕于架构的一系列模式,将架构元素、特征进行组合与呈现,并将架构决策与设计原则等紧密的与系统相结合。
而为了实施及落地架构即代码的理念,还需要构建一个运行这些代码的平台,我们称它称为架构工作台。可是,为什么我们要构建一个架构工作台?仅仅是为了好玩。
在 ArchGuard 中,我们想治理的是架构的三种形态:设计态、开发态和运行态。对应于:
设计新的企业(应用)架构。诸如于描述和设计系统的当前架构。
理解和管控系统的现状。诸如于通过可视化的手段展示系统的现状、以规则来管理系统。
观测系统 <=> 架构的运行。
同样,对于诸多中大型组织师的架构相关的部门来说,他们同样存在上述的这些问题。并且,我相信他们也面临着同我们构建 ArchGuard 时一样的困境:
架构是多维的。包含技术、数据、安全、运维与系统等
缺乏统一的架构语言。用于沟通的人类语言,诸如于什么是组件?
系统的架构千奇百怪。架构风格或模式差异,如微服务架构、插件化架构等。
缺乏业务上下文。作为一个外部架构师,帮助治理时缺乏一些上下文。
细节是魔鬼。架构的世界丰富多彩,没有办法一一展现出来,比如一个小小的接口,可能会反转我们对于理解的假设。
我们(ArchGuard 团队)目前的架构能力有限(~~这个不会写出来的~~)—— 资深架构师太少。
所以,在实现这样一个标准化的架构模式系统之前,不如尝试构建一个更灵活的形式:架构工作台。它可以帮助我们更好地探索系统,也更符合我们的初期体验。
对于工作台这一概念来说,作为一个活跃的 DSL 创造者,我比较熟悉的是 Martin Fowler 在《领域特定语言》中对于语言工作台的定义:
语言工作台是一个环境,其设计初衷就是帮助人们构建新的 DSL,以及有效地运用这些 DSL 所需的高质量工具。
也因此在定义上,我们参考了老马的定义,并借鉴了现代化的工作台理念,主要有:RStudio 的代码文档化、Jupyter 的交互性分析。所以,我们的定义是:
架构工作台是一个环境,其设计初衷用于帮助人们设计架构、演进架构、观测架构,并有效地运用架构所需要的高质量工具,如交互式的架构开发和分析。
代码文档化,用于帮助我们更好地管理架构代码,将它融入软件开发生命周期里,如架构文档、用户故事、持续集成等。而交互性分析,则是用于帮助我们有效减少定制的代码,进而演变为提供的是 API 接口,与其定制化的代码。
对于架构工作台来说,它应用包含了以下一些核心功能与特性:
设计架构、演进架构与观测架构。
构建架构的数字孪生
说明性编程与显式设计
在这些特性中,我们认为构建架构的数字孪生是这个工作台最应该被重视的部分,而基础块则是:设计架构、演进架构与观测架构。
在治理架构时,我们通常会关注于如何设计,如何演进,以及观测架构在运行时的状态。
设计架构。这样的功能其并不能理解,难点是,如何提供高效的设计机制?采用 UI 拖拉拽的方式,又或者是 DSL,都有各种的博弈。总体来说使用代码会更加友好。而为了直观的展示架构的设计,我们会通过架构图来表示,这也就是系统的核心。
演进架构。其核心是构建架构治理模型和设计架构的适应度函数,以引导系统进行有序的变更。从实现的层面来说,就是从对实现出来的软件架构(即代码等)进行分析,设计度量指标,并提供高质量的工具,来引导架构回归到合理的状态。
观测架构。即观察架构的应用的运行状态,主要依靠于各类的 APM(application performance management,应用性能监测)工具。在云原生时代,相关的工具也非常的流行,如 Skywalking 等。
一个基础的架构工作台,应该考虑上述的三个要素。
理想的架构工作台,它应该提供一个可交互的架构的映射版本。它意味着:它是对系统或对象在其整个生命周期中的虚拟表示,我们可以根据实时数据进行更新,并使用模拟、机器学习和推理来帮助决策。
从概念上来说,它提供了一个非常美好的未来,难点就在于如何实现这样的系统?
我们正在设计 ArchGuard 的数字孪生版本,则围绕于这三种形态的架构形式(从实现的层面考虑的):
设计态。关注于边界、概念与交互。
开发态。关注于层级、依赖与模块。
运行态。关注于性能、链路层级与资源使用。
这个版本相当于是设计态,在实现的时候,还会受到开发能力和数据上的制约。未来,我们是不是也应该代码及其架构孪生的双向绑定?
我们所熟悉的各类架构相关的规范,它存在着诸多的问题,诸如于:规范不直观、规范没有自动化等。为了有效的演进架构,我们需要有效地结合规范、代码、设计,也就是说明性编程与显性设计,它们都是来自于 PL(编程语言)/ DSL(领域特定语言)中的概念。
说明性编程(illustrative programming)是用于加强执行结果的解释性,如在架构治理的场景下,通过生成架构图来理解 DSL 编写的结果。另外一类觉的方式,有诸如于 Excel 中的表格和图表等。详细可以查看文末 Martin Fowler 的相关文章。
显式设计。显式是通过明确编写要完成的指示来完成所需更改的手动方法。显示设计则是指引我们如何构建好系统的描述语言,诸如于 ADL(架构描述语言)的 DSL。除了,使用贴进架构描述的语言,还有用于支撑 DSL 的工具支撑,如编辑器智能感知。
这两个特性是围绕于架构即代码这一理念所改善的,诸如于 PlantUML、Graphviz 这一类图表即代码(Diagrams as code)也具备了这样的特质。
当然,为了让这个系统更好用,我们还需要其它的一系列特性:
架构演进的模拟验证。
易于扩展的功能。即采用微内核架构,即插件化、微前端化等。
依旧还有诸多东西可以探索,等待我们构建完第一个版本后,再展开讨论。
我们现在 ArchGuard 中实践一个这样的系统,它相当地令人激动。作为一个早期的版本,它勉强可以工作,如下是我们构建系统的一些思路。
由于,系统是一个类似于数据分析的系统,所以我们的诸多流感来源于大数据领域。在工作台上,起初,我们的想法是构建一个采用 RStudio 似的可编译报告,并提供类似于 Jupyter 的交互体验。
可由于 Jupyter 的交互体验太差,下载的文件又没有可读性,不能方便地编辑 + 运行。所以,我们采用了 Markdown 作为数据格式,方便于开发人员编写文档,也可以在任意的 IDE 中打开和编辑。在 UI 上,则是采用 ProseMirror 主编辑器,即 Markdown 的编辑器,采用 Monaco Editor 作为副编辑器,即代码的编辑器。
考虑到了 IDE 支持,我们采用了 Kotlin 来构建内部 DSL,这样就无需外部 DSL 需要构建编辑器支持。接着,就采用了 Kotlin Scripting Compiler 作为底层的 REPL(read–eval–print loop,也称为交互式顶层构件),简单来说,就是 Kotlin 语言的命令行模式。从形态上来说,类似于 MySQL Workbench 的形式,又或者说是 Python 的 CLI 模式。
随后,便是抽象系统(ArchGuard)、设计态的架构、架构适应度函数的 DSL。
在有了编译器后端的支持及 Kotlin DSL 的 IDE 之后,我们需要构建双者的桥梁。于是,我们采用 WebSocket 作为通信方式,返回结果上按不同的类型处理。诸如于:
集成后端 API 的运行结果。
图形结果。Mermaid、D3.js、Echart.js 是针对于不同图形展示。
执行对应的扫描。
与通常的 C/S 结构开发无异。图形化的结果,用于支持我们的说明性编程与显性设计。
我们依旧在设计和构建这样的工作台,欢迎随时来勾搭我们:https://github.com/archguard/archguard 。
参考内容:
《领域特定语言》
《演进式架构》
《利用 Python 进行数据分析》
《IllustrativeProgramming》