每日一博 | 轻量级的架构决策记录机制
作者:倪新明
ADR是一种性价比非常高的架构决策文档化实践,团队引入和实践成本很低,却能为团队带来极大收益!
1 团队研发面临的问题
不论是在传统的IT行业,还是互联网行业,研发团队在架构决策层面或多或少的都会面临以下问题或挑战:
基于以上这些问题,我们想:
通过文档形式记录架构决策首当其冲的问题是:文档过期!!
确实,过期问题是文档化必然面临的问题。无论通过什么机制,比如强流程、自动化更新等都存在过期风险。那为什么还要选择记录架构决策呢?基于以下两个原因:
2 ADR剖析
Architecture Decision Record,缩写ADR,即架构决策记录,该实践最先由Michael Nygard发起,是记录架构决策最有效的方式之一。简单来说,ADR是一种对架构决策的文档化记录,其目的是通过文档化的形式记录系统的架构决策、原因以及决策过程。
通过对系统架构决策进行有效记录,团队可以从以下几个层面获得收益:
建议的ADR的基本结构包括标题、状态、背景、决策、影响共五个部分,一般情况下,推荐增加一致性和备注两个极具价值的额外章节作为补充。
需要说明的是,团队可以按需增加其他章节以增强ADR的表现能力,比如增加可选方案章节对可选方案进行详细描述。
标题【必选】
ADR的 “标题” 部分主要包括两部分,其一是顺序编号,其二是对架构决策的简短描述。标题的描述需要确保对架构决策进行准确描述、清晰无歧义,同时,也要保持简短明了。
例如:ADR 01. 订单服务和履约服务之间采用异步消息机制
状态【必选】
ADR的 "状态" 限定为 待审核 , 审核通过,被取代 三种状态之一。
背景【必选】
推动架构师对此项架构决策的具体背景或问题进行描述,以及简洁扼要地表述可能的可选方案。决策背景在一定程度上也是对系统架构的一种描述。
说明:不建议在此章节进行详细的替代方案分析和说明,如果确实需要进行详细阐述,则建议增加额外的章节进行说明。
可选方案【可选】
对可选的替代方案进行详细描述,对比不同方案的优劣势
决策【必选】
该部分包含了具体的架构决策以及相应的决策依据,原则上要使用肯定式、命令式的描述方式表述具体的架构决策,不要存在主观的、消极的、模棱两可的、可能存在歧义的措辞。说明:关注Why 而非 How,理解架构决策的原因比理解怎么实现更加重要
影响【必选】
该部分描述此项架构决策的整体影响。每项决策都会或多或少的对现有系统产生影响,包括好的影响和坏的影响,通过该章节推动架构师思考这些影响是否超过架构决策的收益。
一致性【可选】
该部分并不是标准ADR元素,但同样颇具价值,其作用在于推动架构师从架构一致性的视角思考所作架构决策如何进行度量和治理。架构师必须确定该项架构决策的一致性保证是通过人工方式还是通过自动化方式实现。如果可以通过自动化方式进行,则在该章节明确说明自动化的执行方案。
备注【必选】
备注部分并不是标准ADR的结构,但是强烈推荐增加该章节。备注部分主要包含的ADR的各种元数据,例如:
原作者、审核日期、审核人、替代日期、最后修改日期、修改人、最后修改内容
说明:有些团队认为备注部分的元数据信息没有太大价值,特别是,当团队将ADRs与代码一同存储在配置库时(并不推荐该种存储方式)。但实际上,将元信息作为ADR的一部分比依赖配置库更具价值和优势。
3 ADR的组织和存储
ADR文档具体存放在什么位置,比如FTP服务器、WIKI或者同项目代码配置库,不同的团队可以根据情况进行灵活选择。原则:ADR能够被干系人便捷地获取。
方式一:基于类似Git的配置库存储
优点:
缺点:
ADR的干系人不仅仅是研发人员,还有技术经理、产品经理、业务人员等其他角色的项目干系人。基于太技术性的配置库进行存储,显然对除研发以外的角色不太友好。同时,还需要对非研发人员开通仓库权限,代码安全性也是须要考虑的因素。另外,基于配置库存储不太方便存放同一系统不同应用下通用的架构决策以及应用间的集成架构决策。
方式二:类似WIKI的在线协同编辑共享系统内
优点:干系人友好在线协作方便处理跨应用的架构决策
缺点:开发人员不友好,离开发库较远
基于对跨应用架构决策的存储,团队选择将ADR存储在在线协同文档平台,并通过合理的文件夹结构进行组织,参考以下组织形式:
4 ADR融入研发流程
如果要落地ADR,则须要将其融入到现有的研发过程中。ADR涵盖的流程活动主要是:
制定ADR
评审ADR
5 ADR实践过程中的常见疑问
问题一:写ADR的 “时间成本较高” ,延长了技术方案设计周期 ?
答:否!
该疑问可能主要来自于以下几个原因:
但实际上,如果作为架构决策者具备决策分析的习惯,特别是在技术方案设计时,进行过充分的决策分析,1-2页的ADR文档撰写不会超过 1 个小时,甚至在半个小时内完成。即使制定和评审ADR影响了一小部分设计时间,通过对关键决策的充分分析和审重决策所带来的价值远胜过返工造成额外成本
问题二:遗留系统没有必要再写ADR ?
答:否!
价值是决定是否写ADR的因素之一,切忌ADR只对当前架构决策进行记录。对于遗留系统,在团队遗忘之前,记录其关键架构决策依然具有较大价值。
问题三:ADR这种文档化机制与敏捷冲突 ?
答:否!
敏捷宣言中指出:可以工作的软件胜过面面俱到的文档。其强调左侧更有价值,但不否定右侧的价值。
因此,文档化并不一定与敏捷理念发生冲突。通过采用轻量级的文档机制,记录具有核心价值的东西,确保文档机制不会成为团队负担,本身与敏捷文化相互契合。
问题四:ADR评审是不是流程太重 ?
答:可能,但是有必要!
ADR评审是引入ADR机制的重要活动之一,不可忽略!正是通过多干系人参与下的评审活动,才能产生ADR的诸多重要价值。通过这种正式或非正式的评审活动:
因此,ADR的评审活动是必要的,从效率考虑,团队可以优化评审过程。
问题五:ADR模板很多,团队应该如何选择?
答:没有标准的,只有最适合的 !
ADR没有统一的模板,选择适合团队的,建议:
模板保持轻量,不要试图覆盖所有的场景,否则,ADR会成为团队成员的负担
更重要的是,ADR模板和模板元素的含义一定要在团队成员间达成一致
问题六:什么时候需要写ADR没有量化条件,所以很难落地?
答:否!
原则上:对系统产生显著影响的架构决策需要写ADR。
如何定义 "显著影响" 没有量化指标,但如果存在以下场景可能是需要写ADR的信号:
以上场景只是可能需要写ADR的一些信号,但并不是强制约定。
是否需要写ADR的终极实践准则是:具体情况,具体分析
6 ADR撰写中的常见误区
ADR的结构虽然非常简单,但团队在开始实践过程时对于每个章节的内容表述极易出现偏差,在撰写ADR文档时常见的问题如下:
【背景】部分
典型反例:
未直接说明推动进行决策的原因:正确的方式是要明确说明进行此次架构决策的背景或动机是什么,明确 WHY对可选方案进行详细说明:ADR实践初期,团队常犯的错误式在 “背景” 部分对方案进行详细的大篇幅论述
【决策】部分
典型反例:
缺少决策依据说明:决策依据过于简单,不充分,不能推到选择当前决策的论据决策结果表述措辞不够明确、模棱两可
【可选方案】部分
典型反例:分析角度存在明显倾向性,不够客观
【一致性】部分
该章节的目的是推动架构师对如何确保决策被团队遵守进行深入思考,特别是考虑是否可以通过自动化方式进行。典型的反例词汇是:系统落地、开发实现......
如果不能不同自动化方式进行检查,可能 设计评审、同行代码评审、专家代码评审是可能的方式如果可以通过自动化方式进行,则要说明如何进行自动化方式进行约束校验。例如,如果工程实践通过Archunit进行单测,则可以表述基于Archunit的规则代码。
7 结语
ADR不仅仅是一份文档,团队将获得以下收益:
开始团队的ADR之旅吧!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Apache Zeppelin 存储型XSS漏洞
漏洞描述 Apache Zeppelin是一款基于 Web 可实现交互式数据分析的notebook产品。 由于Apache Zeppelin <0.8.2 版本中helium.controller.js文件未对name参数进行转义,导致存在存储型xss漏洞,具有登陆权限的攻击者可利用该漏洞对其他用户浏览器执行任意javascript代码。 漏洞名称 Apache Zeppelin 存储型XSS漏洞 漏洞类型 XSS 发现时间 2022-12-17 漏洞影响广度 一般 MPS编号 MPS-2022-67319 CVE编号 CVE-2022-46870 CNVD编号 - 影响范围 org.apache.zeppelin:zeppelin-web@[0.6.0, 0.8.2) 修复方案 将组件 org.apache.zeppelin:zeppelin-web 升级至 0.8.2 及以上版本 参考链接 https://www.oscs1024.com/hd/MPS-2022-67319 CVE Commit 情报订阅 OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布...
- 下一篇
Rubik —— Android 平台组件化开发框架
Rubik是一套解决Android平台组件化的综合方案,提供gradle project之间的路由通讯能力,以及对gradle project的组件定义、版本控制、maven发布、aar/jar与源码之间的切换以及组件的自由组合等能力。 English Readme Rubik由两部分组成: Rubik Router :即Rubik的函数级路由能力,与一般的页面路由不同,Rubik Router允许把Uri及参数,导航到工程内部,任意的一个公开的JVM语言(Java/Kotlin)函数的执行上,以便于更灵活的进行gradle project之间不基于代码调用的通讯。 Rubik 工具链 :提供组件上下文的定义、版本控制、maven发布、aar/jar与源码之间的切换等能力,包括4个gradle plugin: rubik: 提供全局定义组件的能力,并根据全局定义自动启用rubik-context、rubik-root等插件 rubik-context: 提供task,自动生成镜像函数等中间代码,并把中间代码打包成context.jar ,按版本号发布到maven 提供task,把业务代...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Red5直播服务器,属于Java语言的直播服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7