速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

Apache 的架构师们遵循的 30 条设计原则

  • 2020-05-06
  • 本文字数:2752 字

    阅读完需:约 9 分钟

Apache 的架构师们遵循的 30 条设计原则

Srinath 通过不懈的努力最终总结出了 30 条架构原则,他主张架构师的角色应该由开发团队本身去扮演,而不是专门有个架构师团队或部门。Srinath 认为架构师应该扮演的角色是一个引导者,讨论发起者,花草修建者,而不是定义者和构建者。Srinath 为了解决团队内部的架构纷争和抉择,制定了以下 30 条原则,这些原则被成员们广泛认可,也成为了新手架构师的学习途径。



Photo by Muyuan Ma on Unsplash


基本原则


原则 1:KISS(Keep it simple,sutpid) 和保持每件事情都尽可能的简单。用最简单的解决方案来解决问题。


原则 2:YAGNI(You aren’t gonna need it)-不要去搞一些不需要的东西,需要的时候再搞吧。


原则 3:爬,走,跑。换句话说就是先保证跑通,然后再优化变得更好,然后继续优化让其变得伟大。迭代着去做事情,敏捷开发的思路。对于每个功能点,创建里程碑(最大两周),然后去迭代。


原则 4:创建稳定、高质量的产品的唯一方法就是自动化测试。所有的都可以自动化,当你设计时,不妨想想这一点。


原则 5:时刻要想投入产出比(ROI)。就是划得来不。


原则 6:了解你的用户,然后基于此来平衡你需要做哪些事情。不要花了几个月时间做了一个 devops 用户界面,最后你发现那些人只喜欢命令行。此原则是原则 5 的一个具体表现。


原则 7:设计和测试一个功能得尽可能的独立。当你做设计时,应该想想这一条。从长远来看这能给你解决很多问题,否则你的功能只能等待系统其他所有的功能都就绪了才能测试,这显然很不好。有了这个原则, 你的版本将会更加的顺畅。


原则 8:不要搞花哨的。我们都喜欢高端炫酷的设计。最后我们搞了很多功能和解决方案到我们的架构中,然后这些东西根本不会被用到。

功能选择

原则 9:不可能预测到用户将会如何使用我们的产品。所以要拥抱 MVP(Minimal Viable Product),最小可运行版本。这个观点主要思想就是你挑几个很少的使用场景,然后把它搞出来,然后发布上线让用户使用,然后基于体验和用户反馈再决定下一步要做什么。


原则 10:尽可能的做较少的功能。当有疑问的时候,就不要去做,甚至干掉。很多功能从来不会被使用。最多留个扩展点就够了。


(小编点评:产品经理可能是听不进去的,最好采取数据度量说话…)


原则 11:等到有人提出再说(除非是影响核心流程,否则就等到需要的时候再去做)。


原则 12:有时候你要有勇气和客户说不。这时候你需要找到一个更好的解决方案来去解决。记住亨利福特曾经说过的 :”如果我问人们他们需要什么,他们会说我需要一匹速度更快的马”。记住:你是那个专家,你要去引导和领导。要去做正确的事情,而不是流行的事情。最终用户会感谢你为他们提供了汽车。

服务端设计和并发

原则 13:要知道一个 server 是如何运行的,从硬件到操作系统,直到编程语言。优化 IO 调用的数量是你通往最好架构的首选之路。


原则 14:要了解 Amdhal 同步定律。在线程之间共享可变数据会让你的程序变慢。只在必要的时候才去使用并发的数据结构,只在必须使用同步(synchronization)的时候才去使用同步。如果要用锁,也要确保尽可能少的时间去 hold 住锁。如果要在加锁后做一些事情,要确保自己在锁内会做哪些事情。


原则 15:如果你的设计是一个无阻塞且事件驱动的架构,那么千万不要阻塞线程或者在这些线程中做一些 IO 操作,如果你做了,你的系统会慢的像骡子一样。

分布式系统

原则 16:无状态的系统的是可扩展的和直接的。任何时候都要考虑这一点,不要搞个不可扩展的,有状态的东东出来,这是起码的。


原则 17:保证消息只被传递一次,不管失败,这很难,除非你要在客户端和服务端都做控制。试着让你的系统更轻便(使用原则 18)。你要知道大部分的承诺 exactly-once-delivery 的系统都是做了精简的。


原则 18:实现一个操作尽可能的幂等。这样的话就比较好恢复,而且你还处于至少一次传递(at least once delivery)的状态。


原则 19:知道 CAP 理论。可扩展的事务(分布式事务)是很难的。如果可能的的话,尽可能的使用补偿机制。RDBMS 事务是无法扩展的。


原则 20:分布式一致性无法扩展,也无法进行组通信,也无法进行集群范围内的可靠通信。理想情况下最大的节点限制为 8 个节点。


原则 21:在分布式系统中,你永远无法避免延迟和失败。

用户体验

原则 22:要了解你的用户和清楚他们的目标。他们是新手、专家还是偶然的用户?他们了解计算机科学的程度。极客喜欢扩展点,开发者喜欢示例和脚本,而普通人则喜欢 UI。


原则 23:最好的产品是不需要产品手册的。


原则 24:当你无法在两个选择中做决定的时候,请不要直接把这个问题通过提供配置选项的方式传递给用户。这样只能让用户更加的发懵。如果连你这个专家都无法选择的情况下,交给一个比你了解的还少的人这样合适吗?最好的做法的是每次都找到一个可行的选项;次好的做法是自动的给出选项,第三好的做法是增加一个配置参数,然后设置一个合理的默认值。


原则 25:总是要为配置设置一个合理的默认值。


原则 26:设计不良的配置会造成一些困扰。应该总是为配置提供一些示例值。


原则 27:配置值必须是用户能够理解和直接填写的。比如:不能让用户填写最大缓存条目的数量,而是应该让用户填写可被用于缓存的最大内存。


原则 28:如果输入了未知的配置要抛出错误。永远不要悄悄的忽略。悄悄的忽略配置错误往往是找 bug 花了数小时的罪魁祸首。

艰难的问题

原则 29:梦想着新的编程语言就会变得简单和明了,但往往要想真正掌握会很难。不要轻易的去换编程语言。


原则 30:复杂的拖拉拽的界面是艰难的,不要去尝试这样的效果,除非你准备好了 10 人年的团队。


最后,说一个我的感受。在一个理想的世界里,一个平台应该是有多个正交组件组成-每个组件都负责一个方面(比如,security,messaging,registry,mdidation,analytics)。好像一个系统构建成这样才是完美的。但不幸的是,现实中我们很难达到这样的状态。因为在项目初始状态时,很多事情是不确定的,你无法做到这样的独立性,现在我更倾向于在开始的时候适当的重复是必要的,当你尝试铲除他们的时候,你会发现引入了新的复杂性,分布本身就意味着复杂。有时候治愈的过程要比疾病本身更加的糟糕。

总结

作为一个架构师,应该像园丁一般,更多的是修剪花草,除草而不是去定义和构建,你应该策划而不是指挥,你应该去修剪而不是去定义,应该是讨论而不是贴标签。虽然在短期内可能会觉得也没什么,但从长远看,指导团队找到自己的方式会带来好处。如果你稍不留神,就很容易让架构成为一个空洞的词汇。比如设计者会说他的架构是错误的,但不知道为什么是错误的。一个避免这种情况的好办法就是有一个原则列表,这个原则列表是被广泛接受的,这个列表是人们讨论问题的锚点,也是新手架构师学习的路径。


本文转载自技术琐话公众号。


原文链接:https://mp.weixin.qq.com/s/QOaPepaIQwo4J1HlREBSWQ


2020-05-06 10:241323

评论 1 条评论

发布
用户头像
译文有一点含义不对了

译文
原则 14:要了解 Amdhal 同步定律。在线程之间共享可变数据会让你的程序变慢。只在必要的时候才去使用并发的数据结构,只在必须使用同步(synchronization)的时候才去使用同步。如果要用锁,也要确保尽可能少的时间去 hold 住锁。如果要在加锁后做一些事情,要确保自己在锁内会做哪些事情。

原文
https://medium.com/hackernoon/first-do-no-harm-30-principles-that-helped-me-avoid-fly-by-architecture-reviews-e8952ac632a

Principle 14: Know Amdhal’s law about synchronization. Mutable data shared between threads slows your program. Use concurrent data structures if you can, and use synchronization only if you must. Try to hold the locks as little time as possible. If you plan to block while holding a lock, make sure you know what you are doing. If it can break, it will.

“当需要并发访问时,如果可以则总是使用并发的数据结构”;“如果持有锁时需要阻塞,确保知道自己在做什么(意思是这么做不好,会大大降低吞吐量,因为持有锁时阻塞会导致 所有需要获取锁的其他线程 都不得不等待)。如果可能失败,那就一定会失败”
展开
2020-06-21 15:44
回复
没有更多了
发现更多内容

详解CAN总线:CAN总线故障界定与管理

不脱发的程序猿

汽车电子 CAN总线 CAN总线故障界定 CAN错误故障诊断

GaussDB(DWS)如何实现实时,批量和交付式查询一站式开发

乌龟哥哥

10月月更

【愚公系列】2022年10月 Go教学课程 035-接口和继承和转换与空接口

愚公搬代码

10月月更

YARN基本架构

穿过生命散发芬芳

YARN 10月月更

golang中的切片

六月的

Go slice

数据湖(六):Hudi与Flink整合

Lansonli

10月月更 Hudi与Flink整合

RxJava的操作符

急需上岸的小谢

10月月更

加密标准中DES与AES到底是什么?两者有啥区别?

wljslmz

信息安全 加密 AES 10月月更 DES

Feign的两个调用处理器

急需上岸的小谢

10月月更

Git 操作命令笔记

宇宙之一粟

git 10月月更

“程”风破浪的开发者|如何更好的学习专业知识

闫同学

学习方法 10月月更 “程”风破浪的开发者

【一Go到底】第二十一天---defer

指剑

Go golang 10月月更

过去几个月,他们把数字化融进了中国经济的毛细血管

脑极体

Vue组件入门(十一)$attrs

Augus

Vue 3 10月月更

“程”风破浪的开发者|代码规范

over℡

学习方法 “程”风破浪的开发者

微信小程序云开发收费调整,大家怎么看?

江拥羡橙

微信小程序 云开发 10月月更

el-table表格还可以这么玩

江拥羡橙

Vue 3 Element UI 10月月更

数据开发也能双轮驱动?

乌龟哥哥

10月月更

CentOS 上安装 Sonatype Nexus 仓库

HoneyMoose

Glibc-scratch_buffer的源码分析

桑榆

源码刨析 10月月更 C++

2022-10-20:以下go语言代码输出什么?A:7;B:7.0;C:0;D:编译错误。 package main import ( “fmt“ ) func main() { const

福大大架构师每日一题

golang 福大大 选择题

Spring Batch 中的 chunk

HoneyMoose

群晖(Synology)NAS 安装 MongoDB

HoneyMoose

【资损】资损防控的系统规范-渠道网关类设计

小明Java问道之路

架构 安全 金融 10月月更 资损

PHP出发(php+apache+MySQL)

江拥羡橙

php MySQL apache 社区 10月月更

feign client客户端的自动装配

急需上岸的小谢

10月月更

“程”风破浪的开发者|Web3.0是什么?带你解析Web3.0

梦笔生花

Web3.0 “程”风破浪的开发者 Web2.0

智能化运维场景分析

阿泽🧸

10月月更 智能化运维

【设计模式】Java 语言不同的编程范式-第1章

跟着飞哥学编程

设计模式 编程范式 java 编程 10月月更

SAP | 内部表的表类型

暮春零贰

SAP 10月月更 内部表

Sonatype Nexus 管理员初始密码

HoneyMoose

Apache 的架构师们遵循的 30 条设计原则_架构_技术琐话_InfoQ精选文章