架构实践方法

一、识别复杂度

将主要的复杂度问题列出来,然后根据业务、技术、团队等综合情况进行排序,优先解决当前面临的最主要的复杂度问题。对于按照复杂度优先级解决的方式,存在一个普遍的担忧:如果按照优先级来解决复杂度,可能会出现解决了优先级排在前面的复杂度后,解决后续复杂度的方案需要将已经落地的方案推倒重来。这个担忧理论上是可能的,但现实中几乎是不可能出现的,原因在于软件系统的可塑性和易变性。对于同一个复杂度问题,软件系统的方案可以有多个,总是可以挑出综合来看性价比最高的方案。

二、设计备选方案

架构师的工作并不神秘,成熟的架构师需要对已经存在的技术非常熟悉,对已经经过验证的架构模式烂熟于心,然后根据自己对业务的理解,挑选合适的架构模式进行组合,再对组合后的方案进行修改和调整。

新技术都是在现有技术的基础上发展起来的,现有技术又来源于先前的技术。将技术进行功能性分组,可以大大简化设计过程,这是技术“模块化”的首要原因。技术的“组合”和“递归”特征,将彻底改变我们对技术本质的认识。

1.第一种常见的错误:设计最优秀的方案。
根据架构设计原则中“合适原则”和“简单原则“的要求,挑选合适自己业务、团队、技术能力的方案才是好方案;否则要么浪费大量资源开发了无用的系统(例如,之前提过的“亿级用户平台”的案例,设计了 TPS 50000 的系统,实际 TPS 只有 500),要么根本无法实现(例如,10 个人的团队要开发现在的整个淘宝系统)。

2.第二种常见的错误:只做一个方案。
这样做有很多弊端:

心里评估过于简单,可能没有想得全面,只是因为某一个缺点就把某个方案给否决了,而实际上没有哪个方案是完美的,某个地方有缺点的方案可能是综合来看最好的方案。

架构师再怎么牛,经验知识和技能也有局限,有可能某个评估的标准或者经验是不正确的,或者是老的经验不适合新的情况,甚至有的评估标准是架构师自己原来就理解错了。

单一方案设计会出现过度辩护的情况,即架构评审时,针对方案存在的问题和疑问,架构师会竭尽全力去为自己的设计进行辩护,经验不足的设计人员可能会强词夺理。

因此,架构师需要设计多个备选方案,但方案的数量可以说是无穷无尽的,架构师也不可能穷举所有方案,那合理的做法应该是什么样的呢?

备选方案的数量以 3 ~ 5 个为最佳。少于 3 个方案可能是因为思维狭隘,考虑不周全;多于 5 个则需要耗费大量的精力和时间,并且方案之间的差别可能不明显。

备选方案的差异要比较明显。例如,主备方案和集群方案差异就很明显,或者同样是主备方案,用 ZooKeeper 做主备决策和用 Keepalived 做主备决策的差异也很明显。但是都用 ZooKeeper 做主备决策,一个检测周期是 1 分钟,一个检测周期是 5 分钟,这就不是架构上的差异,而是细节上的差异了,不适合做成两个方案。

备选方案的技术不要只局限于已经熟悉的技术。设计架构时,架构师需要将视野放宽,考虑更多可能性。很多架构师或者设计师积累了一些成功的经验,出于快速完成任务和降低风险的目的,可能自觉或者不自觉地倾向于使用自己已经熟悉的技术,对于新的技术有一种不放心的感觉。就像那句俗语说的:“如果你手里有一把锤子,所有的问题在你看来都是钉子”。例如,架构师对 MySQL 很熟悉,因此不管什么存储都基于 MySQL 去设计方案,系统性能不够了,首先考虑的就是 MySQL 分库分表,而事实上也许引入一个 Memcache 缓存就能够解决问题。

3.第三种常见的错误:备选方案过于详细。
有的架构师或者设计师在写备选方案时,错误地将备选方案等同于最终的方案,每个备选方案都写得很细。这样做的弊端显而易见:

耗费了大量的时间和精力。

将注意力集中到细节中,忽略了整体的技术设计,导致备选方案数量不够或者差异不大。

评审的时候其他人会被很多细节给绕进去,评审效果很差。例如,评审的时候针对某个定时器应该是 1 分钟还是 30 秒,争论得不可开交。

正确的做法是备选阶段关注的是技术选型,而不是技术细节,技术选型的差异要比较明显。例如,采用 ZooKeeper 和 Keepalived 两种不同的技术来实现主备,差异就很大;而同样都采用 ZooKeeper,一个方案的节点设计是 /service/node/master,另一个方案的节点设计是 /company/service/master,这两个方案并无明显差异,无须在备选方案设计阶段作为两个不同的备选方案,至于节点路径究竟如何设计,只要在最终的方案中挑选一个进行细化即可。

三、评估和选择备选方案

上在完成备选方案设计后,如何挑选出最终的方案也是一个很大的挑战,主要原因有:

每个方案都是可行的,如果方案不可行就根本不应该作为备选方案。

没有哪个方案是完美的。例如,A 方案有性能的缺点,B 方案有成本的缺点,C 方案有新技术不成熟的风险。

评价标准主观性比较强,比如设计师说 A 方案比 B 方案复杂,但另外一个设计师可能会认为差不多,因为比较难将“复杂”一词进行量化

正因为选择备选方案存在这些困难,所以实践中很多设计师或者架构师就采取了下面几种错误的指导思想:

最简派:设计师挑选一个看起来最简单的方案。例如,我们要做全文搜索功能,方案 1 基于 MySQL,方案 2 基于 Elasticsearch。MySQL 的查询功能比较简单,而 Elasticsearch 的倒排索引设计要复杂得多,写入数据到 Elasticsearch,要设计 Elasticsearch 的索引,要设计 Elasticsearch 的分布式……全套下来复杂度很高,所以干脆就挑选 MySQL 来做吧。

最牛派:最牛派的做法和最简派正好相反,设计师会倾向于挑选技术上看起来最牛的方案。例如,性能最高的、可用性最好的、功能最强大的,或者淘宝用的、微信开源的、Google 出品的等。

最熟派:设计师基于自己的过往经验,挑选自己最熟悉的方案。我以编程语言为例,假如设计师曾经是一个 C++ 经验丰富的开发人员,现在要设计一个运维管理系统,由于对 Python 或者 Ruby on Rails 不熟悉,因此继续选择 C++ 来做运维管理系统。

领导派:领导派就更加聪明了,列出备选方案,设计师自己拿捏不定,然后就让领导来定夺,反正最后方案选的对那是领导厉害,方案选的不对怎么办?那也是领导“背锅”。

正确的做法是:列出我们需要关注的质量属性点,然后分别从这些质量属性的维度去评估每个方案,再综合挑选适合当时情况的最优方案。

常见的方案质量属性点有:性能、可用性、硬件成本、项目投入、复杂度、安全性、可扩展性等。在评估这些质量属性时,需要遵循架构设计原则 1“合适原则”和原则 2“简单原则”,避免贪大求全,基本上某个质量属性能够满足一定时期内业务发展就可以了。

按优先级选择,即架构师综合当前的业务发展情况、团队人员规模和技能、业务发展预测等因素,将质量属性按照优先级排序,首先挑选满足第一优先级的,如果方案都满足,那就再看第二优先级……以此类推。那会不会出现两个或者多个方案,每个质量属性的优缺点都一样的情况呢?理论上是可能的,但实际上是不可能的。在做备选方案设计时,不同的备选方案之间的差异要比较明显,差异明显的备选方案不可能所有的优缺点都是一样的。如:

架构师经过思考后,给出了最终选择备选方案 2,原因有:

排除备选方案 1 的主要原因是可运维性,因为再成熟的系统,上线后都可能出问题,如果出问题无法快速解决,则无法满足业务的需求;并且 Kafka 的主要设计目标是高性能日志传输,而我们的消息队列设计的主要目标是业务消息的可靠传输。

排除备选方案 3 的主要原因是复杂度,目前团队技术实力和人员规模(总共 6 人,还有其他中间件系统需要开发和维护)无法支撑自研存储系统(参考架构设计原则 2:简单原则)。

备选方案 2 的优点就是复杂度不高,也可以很好地融入现有运维体系,可靠性也有保障。

针对备选方案 2 的缺点,架构师解释是:

备选方案 2 的第一个缺点是性能,业务目前需要的性能并不是非常高,方案 2 能够满足,即使后面性能需求增加,方案 2 的数据分组方案也能够平行扩展进行支撑(参考架构设计原则 3:演化原则)。

备选方案 2 的第二个缺点是成本,一个分组就需要 4 台机器,支撑目前的业务需求可能需要 12 台服务器,但实际上备机(包括服务器和数据库)主要用作备份,可以和其他系统并行部署在同一台机器上。

备选方案 2 的第三个缺点是技术上看起来并不很优越,但我们的设计目的不是为了证明自己(参考架构设计原则 1:合适原则),而是更快更好地满足业务需求。

四、详细方案设计

详细设计方案阶段可能遇到的一种极端情况就是在详细设计阶段发现备选方案不可行,一般情况下主要的原因是备选方案设计时遗漏了某个关键技术点或者关键的质量属性。这种情况可以通过下面方式有效地避免:

架构师不但要进行备选方案设计和选型,还需要对备选方案的关键细节有较深入的理解。例如,架构师选择了 Elasticsearch 作为全文搜索解决方案,前提必须是架构师自己对 Elasticsearch 的设计原理有深入的理解,比如索引、副本、集群等技术点;而不能道听途说 Elasticsearch 很牛,所以选择它,更不能成为把“细节我们不讨论”这句话挂在嘴边的“PPT 架构师”。

通过分步骤、分阶段、分系统等方式,尽量降低方案复杂度,方案本身的复杂度越高,某个细节推翻整个方案的可能性就越高,适当降低复杂性,可以减少这种风险。

如果方案本身就很复杂,那就采取设计团队的方式来进行设计,博采众长,汇集大家的智慧和经验,防止只有 1~2 个架构师可能出现的思维盲点或者经验盲区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/27613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

List list=new ArrayList()抛出的ArrayIndexOutOfBoundsException异常

1.应用场景,今天生产日志监控到一组new ArrayList() 进行add 异常,具体日志如下: eptionHandler.handler(178): TXXYBUSSINESS|执行异常 java.util.concurrent.CompletionException: java.lang.ArrayIndexOutOfBoundsException: Index 1 out…

银河麒麟QT连接DM8数据库

1. 安装达梦8 官网下载, 按照官方文档进行安装即可. 2. 安装unixodbc 1> 下载odbc安装包 unixODBC-2.3.7pre.tar.gz 2> 解压 tar -xvf unixODBC-2.3.7pre.tar.gz3> 编译 ./configure -prefix /usr/local make && make install4> 查找配置 odbcinst -j5…

【从零学习python 】04. Python编程基础:变量、数据类型与标识符

文章目录 变量以及数据类型一、变量的定义二、变量的类型三、查看数据类型 标识符和关键字标识符命名规则命名规范 关键字进阶案例 变量以及数据类型 一、变量的定义 对于重复使用,并且经常需要修改的数据,可以定义为变量,来提高编程效率。…

代码随想录算法训练营第51天|动态规划part09|198.打家劫舍、213.打家劫舍II、337.打家劫舍III

代码随想录算法训练营第51天|动态规划part09|198.打家劫舍、213.打家劫舍II、337.打家劫舍III 198.打家劫舍 198.打家劫舍 思路: 仔细一想,当前房屋偷与不偷取决于 前一个房屋和前两个房屋是否被偷了。 所以这里就更感觉到&a…

鉴源论坛·观模丨形式化方法的工业应用:轨交领域

作者 | 王依玲 上海控安可信软件创新研究院系统建模组 版块 | 鉴源论坛 观模 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 引言:前面几期文章介绍了形式化方法的发展历史和具体技术,并从整体的角度介绍了形式化方法的工程化。本…

SpringBoot 的事务及使用

一、事务的常识 1、事务四特性(ACID) A 原子性:事务是最小单元,不可再分隔的一个整体。C 一致性:事务中的方法要么同时成功,要么都不成功,要不都失败。I 隔离性:多个事务操作数据库中同一个记录或多个记录时,对事务进…

TikTok推出PrivacyGo,品牌可与平台共享部分用户数据

1.TikTok宣布允许用户关闭内容自动显示功能 TikTok近日宣布修改运营方式,即允许用户关闭内容自动显示功能,以遵守将于8月底生效的欧盟新规定(欧盟数字服务法案DSA),该法案对平台提出了新的要求,以更好地保…

.NET 应用程序 部署

**硬件支持型号 点击 查看 硬件支持 详情** DTU701 产品详情 DTU702 产品详情 DTU801 产品详情 DTU802 产品详情 DTU902 产品详情 G5501 产品详情 本文内容 在设备上部署 dotnet应用,与任何其他平台的部署相同,可以2种方式: 依赖于框…

适配器模式来啦

网上的大多数的资料中适配器模式和代理模式都是紧挨着进行介绍的,为什么呢??? 是因为适配器模式和代理模式有太多的相似之处,可以进行联动记忆但是也要做好区分。 在菜鸟教程中,适配器模式的定义是作为两…

数学类问题(Leetcode)

1.质数数量 nullhttps://leetcode.cn/problems/count-primes/description/解题思路&#xff1a; 遍历大于1 且小于n的每个数的倍数&#xff0c;设置为非质数&#xff0c;剩下的就都是质数了。 代码&#xff1a; class Solution { public:int countPrimes(int n) {if(n<2)…

【机器学习2】什么是Jupyter notebook 新手使用Jupter notebook

什么是Jupyter notebook? Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序&#xff0c;便于创建和共享程序文档&#xff0c;支持实时代码&#x…

机器学习实战13-超导体材料的临界温度预测与分析(决策树回归,梯度提升回归,随机森林回归和Bagging回归)

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战13-超导体材料的临界温度预测与分析(决策树回归,梯度提升回归,随机森林回归和Bagging回归)&#xff0c;这几天引爆网络的科技大新闻就是韩国科研团队宣称发现了室温超导材料-LK-99&#xff0c;这种材料…

Redisson 3.23.1 正式发布,官方推荐的 Redis 客户端

导读Redisson 3.23.1 现已发布&#xff0c;这是一个 Java 编写的 Redis 客户端&#xff0c;具备驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;功能&#xff0c;并获得了 Redis 的官方推荐。 此版本更新内容如下&#xff1a; Improvement 减少了 RLiveObjectSer…

决策树和随机森林对比

1.用accuracy来对比 # -*-coding:utf-8-*-""" accuracy来对比决策树和随机森林 """ from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_wine#(178, 13…

K8S系列文章之 自动化运维利器 Ansible

Ansible-安装 第一步&#xff1a;安装我们的epel扩展源 yum -y install epel-release 我这里会报/var/run/yum.pid 已被锁定&#xff0c;如果没有直接进行下一步 [rootmaster home]# yum -y install epel-release 已加载插件&#xff1a;fastestmirror, langpacks /var/run/…

C语言 用数组名作函数参数

当用数组名作函数参数时&#xff0c;如果形参数组中各元素的值发生变化&#xff0c;实参数组元素的值随之变化。 1.数组元素做实参的情况&#xff1a; 如果已经定义一个函数&#xff0c;其原型为 void swap(int x,int y);假设函数的作用是将两个形参&#xff08;x,y&#xf…

【css】组合器

组合器是解释选择器之间关系的某种机制。在简单选择器器之间&#xff0c;可以包含一个组合器&#xff0c;从而实现简单选择器难以达到的效果。 CSS 中有四种组合器&#xff1a; 后代选择器 (空格)&#xff1a;匹配属于指定元素后代的所有元素&#xff0c;示例&#xff1a;div …

GWJDN-400型2MHZ自动平衡高温介电温谱仪

GWJDN-400型2MHZ自动平衡高温介电温谱仪 关键词&#xff1a;介电常数&#xff0c;高温介电&#xff0c;自动平衡 主要功能&#xff1a; 材料介电常数测试仪 半导体材料的介电常数、导电率和C-V特性液晶材料:液晶单元的介电常数、弹性常数等C-V特性 性能特点: 温度&#xf…

【CSS】说说响应式布局

目录 一、是什么 二、怎么实现 1、媒体查询 2、百分比 3、vw/vh 4、小结 三、总结 一、是什么 响应式设计简而言之&#xff0c;就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。 响应式网站常见特点&#xff1a; 同时适配PC 平板 手机等…

yxBUG记录

1、 原因&#xff1a;前端参数method方法名写错。 2、Field ‘REC_ID‘ doesn‘t have a default value 问题是id的生成问题。 项目的表不是自增。项目有封装好的方法。调用方法即可。 params.put("rec_id",getSequence("表名")) 3、sql语句有问题 检…