和Apache架构师Srinath一起来探讨软件架构设计的30 条原则

简介: 本文作者叫 Srinath,是一位科学家,软件架构师,也是一名在分布式系统上工作的程序员。他是 Apache Axis2 项目的联合创始人,也是 Apache Software 基金会的成员。他是 WSO2 流处理器的联席架构师。Srinath 通过不懈的努力最终总结出了 30 条架构设计原则,他主张架构师的角色应该由开发团队本身去扮演,而不是专门有个架构师团队或部门。Srinath 认为架构师应该扮演的角色是一个引导者,讨论发起者,花草修建者,而不是定义者和构建者。Srinath 为了解决团队内部的架构纷争和抉择,制定了以下原则,这些原则被成员们广泛认可,如果设计者从未听说过这些原则,他

基本原则

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

点评:简单即是复杂!拿你的代码来说,你想要写的简单且容易理解的话,你就需要花更多的时间去思考。

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

点评:你是否有个这样的经历,臆想觉得某个功能以后可能会用到,然后就顺手把它实现了,实际到了后面并没用上,反而造成了代码冗余。 因此,我们不能闭门臆想需要的功能,但是在架构上又要洞察趋势。

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

点评:快速反馈,一个“拍脑袋的里程碑”也好过没有里程碑。

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

点评:单元测试是很有必要的,但是没有一个恒定的标准说你应该怎么去做。同时,一切自动化也要考虑ROI,比如,对于特别易变的页面层。

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

点评:能不用技术去解决的问题,就不要用技术去解决。技术只是解决问题的一种方案,用技术是一件相对成本更高的方案。手里拿着锤子,千万不能看什么都是钉子。

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

点评:是否有站在用户的角度思考问题呢?是否是为了用新技术而用新技术?

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

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

点评: 吴军老师在《数据之美》中说:一个好的方法,通常是最简单明了的方法。数学的本质就是简单和直接的,同理,软件工程也是一样的。

功能选择

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

点评

在《精益创业》的方法论里,提出了“开发(build)- 测量(measure)- 认知(learn)”这样一个反馈循环。就是说,当你有了一个新的想法(idea)时,就把想法开发成产品(code)投入市场,然后,收集数据(data)获取反馈,看看前面的想法是不是靠谱。得到的结果无非是两种:好想法继续加强,不靠谱的想法丢掉算了。不管是哪种结果,你都会产生新的想法,再进入到下一个循环里。在这个反馈循环中,你所获得的认知是最重要的,因为它是经过验证的。在《精益创业》中,这也是一个很重要的概念:经过验证的认知(Validated Learning)。

同时,《精益创业》也提出一个非常重要的概念,最小可行产品,也就是许多人口中的 MVP。简言之,少花钱,多办事

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

点评:当产品经理让我们做一个新的产品特性时,我们可以向产品经理们问一些问题,帮助我们确定产品经理提出的需求确实是经过严格思考的。记住:默认所有需求都不做,直到弄清楚为什么要做这件事。当然,产品经理可能是听不进去的,最好采取数据度量说话。

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

点评:任何功能需求,除非是影响核心功能,否则,不要去做,等到有需要的时候在做。我们做什么产品,本质上不是由我们或者产品经理决定的,而是由用户决定的。

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

点评: 挖掘用户真实需求,比如,用户说我要吃兰州拉面,难道你就给用户做一碗兰州拉面吗?它吃兰州拉面的本质需求是因为他饿了,还是因为它本身就想吃兰州拉面,如果是前者,我们给他一个馒头是不是就解决用户的需求了,并且成本更低。

服务端设计和并发

原则 13:了解服务的工作原理,从硬件到操作系统,再到您的编程语言。 优化 IO 调用的数量是走向最佳架构的首选之路。

原则 14:了解有关同步的阿姆达尔定律(Amdhal’s law)。在线程之间共享可变数据会减慢您的程序。 尽可能使用并发数据结构,但仅在必须时使用同步。 尝试尽可能少地持有锁。 如果您打算在持有锁时阻塞,请确保您知道自己在做什么。

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

分布式系统

原则 16:无状态的系统的是可扩展的和简单的。尽可能熟悉并使用 Shared-Nothing 架构。

点评:Shared-Nothing(SN)架构中不存在集中存储的状态,整个系统中没有资源竞争,这种架构具有非常强的扩张性)。任何时候都要考虑这一点,不要搞个不可扩展的,有状态的系统出来,这是起码的。

原则 17:除非您同时控制客户端和服务器中的代码,否则无论失败与否,只发送一次消息都很困难。试着设计出更轻便的系统(使用原则18)。要知道,大多数承诺exactly-once-delivery的系统都会在某些地方做了精简的。

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

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

原则 20:分布式一致性无法扩展,也无法进行组通信,也无法进行集群范围内的可靠通信。

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

点评:面向fail进行设计。但是你得考虑为你的用户与你的服务提供 SLA,是真的需要 7*24*365 吗?

用户体验(UE)

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

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

点评:我们需要保持我们的产品易用。很多人觉得敏捷开发下不需要文档,实际上,一个系统即是在敏捷开发的情况下,有些必要的文档还是需要的,比如重大更新记录、相关硬件设施等。

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

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

点评:比如说我现在正在做的一个OCR模型训练平台,让不懂算法的小白用户也可以不写代码训练AI模型,为了让产品更简洁,我们屏蔽了很多细节。同时,为了灵活性,我们也提供了高级配置,比如说,模型训练迭代次数。同时,我们也会提供一个合理的模型值,让小白用户训练出来的模型效果也能够到达优良。

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

点评:判断题优于选择题,选择题优于填空题。配置值尽量简洁,理想状态最好为只有是否的判断。

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

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

艰难的问题

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

点评:“技术极客”是听不进去的,因此,我们不如把“个人修炼”和“项目采用”的解决方案分开看待。

原则 30:复杂的拖拉拽的界面是非常困难的,不要去尝试这样的效果,除非团队准备投入 10 人年的时间。

点评:通过拖拉拽建模来代替写代码时很难的,通常需要投入大量的人力。如果说有成功的,那么也是在比较狭小的领域。

最后,让我谈谈随着时间的推移让我改变主意的一些事情。在一个理想的世界里,一个平台应该是有多个正交组件组成-每个组件都负责一个方面(比如,安全、消息传递、注册表、中介、分析)。好像一个系统构建成这样才是完美的。

但不幸的是,现实中我们很难达到这样的状态。因为在项目初始状态时,很多事情是不确定的,你无法做到这样的独立性,现在我更倾向于在开始的时候适当的重复是必要的,当你尝试删除他们的时候,你会发现引入了新的复杂性,分布式本身就意味着复杂。有时候治愈的过程要比疾病本身更加的糟糕。

点评:软件工程从来都没有银弹,不同阶段采用不同的做法,照抄往往会东施效颦。

总结

作为一个架构师,应该像园丁一般,更多的是修剪花草,除草而不是去定义和构建,你应该策划而不是命令,你应该去修剪而不是去定义,应该是讨论而不是贴标签。

虽然在短期内可能会觉得也没什么,但从长远看,指导团队找到并找到自己的方式会带来好处。

如果你稍不留神,就很容易让架构成为一个空洞的词汇。比如,设计者会说他的架构是错误的,但不知道为什么是错误的。避免这种情况的一种方法是制定一套被普遍接受的原则列表,这个列表是人们讨论问题的锚点,也是新手架构师学习的路线。


相关文章
|
2月前
|
存储 SQL 缓存
快手:从 Clickhouse 到 Apache Doris,实现湖仓分离向湖仓一体架构升级
快手 OLAP 系统为内外多个场景提供数据服务,每天承载近 10 亿的查询请求。原有湖仓分离架构,由离线数据湖和实时数仓组成,面临存储冗余、资源抢占、治理复杂、查询调优难等问题。通过引入 Apache Doris 湖仓一体能力,替换了 Clickhouse ,升级为湖仓一体架构,并结合 Doris 的物化视图改写能力和自动物化服务,实现高性能的数据查询以及灵活的数据治理。
快手:从 Clickhouse 到 Apache Doris,实现湖仓分离向湖仓一体架构升级
|
3月前
|
存储 架构师 测试技术
架构之道——人人都是架构师
本文的探讨和编写主要围绕三个方面:架构是什么?架构师要解决的问题有哪些?解决这些问题的方法论是什么?最后作者希望人人都能具备架构师思维。
|
16天前
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
1月前
|
缓存 NoSQL Java
秒杀圣经:10Wqps秒杀,16大架构绝招,一文帮你秒变架构师 (2)
高并发下的秒杀系统设计是一个复杂的挑战,涉及多个关键技术点。40岁老架构师尼恩在其读者交流群中分享了16个关键架构要点,帮助解决高并发下的秒杀问题,如每秒上万次下单请求的处理、超卖问题的解决等。这些要点包括业务架构设计、流量控制、异步处理、缓存策略、限流熔断、分布式锁、消息队列、数据一致性、存储架构等多个方面。尼恩还提供了详细的实战案例和代码示例,帮助读者全面理解和掌握秒杀系统的架构设计。此外,他还分享了《尼恩Java面试宝典》等资源,帮助读者在面试中脱颖而出。如果你对高并发秒杀系统感兴趣,可以关注尼恩的技术自由圈,获取更多详细资料。
秒杀圣经:10Wqps秒杀,16大架构绝招,一文帮你秒变架构师 (2)
|
20天前
|
分布式计算 大数据 Apache
Apache Spark & Paimon Meetup · 北京站,助力 LakeHouse 架构生产落地
2024年11月15日13:30北京市朝阳区阿里中心-望京A座-05F,阿里云 EMR 技术团队联合 Apache Paimon 社区举办 Apache Spark & Paimon meetup,助力企业 LakeHouse 架构生产落地”线下 meetup,欢迎报名参加!
85 3
|
1月前
|
SQL 存储 分布式计算
大数据-157 Apache Kylin 背景 历程 特点 场景 架构 组件 详解
大数据-157 Apache Kylin 背景 历程 特点 场景 架构 组件 详解
25 9
|
1月前
|
缓存 NoSQL Java
秒杀圣经:10Wqps高并发秒杀,16大架构杀招,帮你秒变架构师 (1)
高并发下,如何设计秒杀系统?这是一个高频面试题。40岁老架构师尼恩的读者交流群中,近期有小伙伴在面试Shopee时遇到了这个问题,未能很好地回答,导致面试失败。为此,尼恩进行了系统化、体系化的梳理,帮助大家提升“技术肌肉”,让面试官刮目相看。秒杀系统设计涉及16个架构要点,涵盖业务架构、流量架构、异步架构、分层架构、缓存架构、库存扣减、MQ异步处理、限流、熔断、降级、存储架构等多个方面。掌握这些要点,可以有效应对高并发场景下的秒杀系统设计挑战。
秒杀圣经:10Wqps高并发秒杀,16大架构杀招,帮你秒变架构师 (1)
|
1月前
|
存储 分布式计算 druid
大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制
大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制
53 3
|
1月前
|
存储 SQL 缓存
Apache Doris 3.0 里程碑版本|存算分离架构升级、湖仓一体再进化
从 3.0 系列版本开始,Apache Doris 开始支持存算分离模式,用户可以在集群部署时选择采用存算一体模式或存算分离模式。基于云原生存算分离的架构,用户可以通过多计算集群实现查询负载间的物理隔离以及读写负载隔离,并借助对象存储或 HDFS 等低成本的共享存储系统来大幅降低存储成本。
Apache Doris 3.0 里程碑版本|存算分离架构升级、湖仓一体再进化
|
1月前
|
消息中间件 分布式计算 druid
大数据-154 Apache Druid 架构与原理详解 基础架构、架构演进
大数据-154 Apache Druid 架构与原理详解 基础架构、架构演进
39 2

推荐镜像

更多