当前位置:网站首页>架构基础篇
架构基础篇
2022-07-16 06:44:00 【xiaolyuh123】
架构设计的关键思维是判断和取舍,程序设计的关键思维是逻辑和实现。
架构设计需要考虑的通用问题,性能、可用性、可扩展性、安全性、成本、规模。
架构设计的三大原则,合适优于业界领先、简单优于复杂、迭代优于一步到位。
基础概念
架构指软件系统的顶层结构,它定义了系统由哪些角色组成,角色之间的关系和运作规则。
框架是面向编程或配置的半成品,关注的是“规范”,架构关注的是“结构”。
组件是从技术维度上的复用。
模块是从业务维度上职责的划分。
系统是相互协同可运行的实体。
如下定义了一交易系统的顶层逻辑架构,橙色方块表示了系统内的角色,连线表示了各角色间的关系,箭头表示了运作规则:

架构图
如果你是业务系统的架构师,首先需要思考怎么从业务逻辑的角度把系统拆分成一个个模块角色,其次需要思考怎么从物理部署的角度把系统拆分成组件角色。从不同维护我们可以画出不同纬度的架构图,如学生管理系统,从业务逻辑的角度分解、从物理角度分解和从开发规范的角度分解会产生如下架构图:
- 业务逻辑架构图:

- 物理部署架构图:

- 开发规范架构图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wzHGvw0Y-1657812486717)(https://upload-images.jianshu.io/upload_images/6464086-5705114828d53508.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
无论是架构设计还是画架构图,都应该采取“自顶向下,逐步细化”的方式。以微信为例:

注:L0\L1\L2 指层级,一个 L0 往下可以分解多个 L1,一个 L1 可以往下分解多个 L2,以此类推,一般建议不超过 5 层(L0~L4)。
RUP 4+1视图
逻辑视图:逻辑视图关注功能,不仅包括用户可见的功能,还包括为实现用户功能而必须提供的"辅助功能模块";它们可能是逻辑层、功能模块等。
开发视图:开发视图关注程序包,不仅包括要编写的源程序,还包括可以直接使用的第三方SDK和现成框架、类库,以及开发的系统将运行于其上的系统软件或中间件。开发视图和逻辑视图之间可能存在一定的映射关系:比如逻辑层一般会映射到多个程序包等。
处理视图:处理视图关注进程、线程、对象等运行时概念,以及相关的并发、同步、通信等问题。处理视图和开发视图的关系:开发视图一般偏重程序包在编译时期的静态依赖关系,而这些程序运行起来之后会表现为对象、线程、进程,处理视图比较关注的正是这些运行时单元的交互问题。
物理视图:物理视图关注"目标程序及其依赖的运行库和系统软件"最终如何安装或部署到物理机器,以及如何部署机器和网络来配合软件系统的可靠性、可伸缩性等要求。物理视图和处理视图的关系:处理视图特别关注目标程序的动态执行情况,而物理视图重视目标程序的静态位置问题;物理视图是综合考虑软件系统和整个IT系统相互影响的架构视图。

架构设计的目的
架构即(重要)决策,是为了应对软件系统复杂度而提出的一个解决方案,主要从性能、可用性、可扩展性、安全性、成本、规模等几个方面进行考虑,但和具体业务相结合,不需要面面俱到。
复杂度来源
高性能
衡量软件性能包括了响应时间、TPS(意思是每秒事务数,事务可以是一个接口)、QPS、服务器资源利用率等。
提高系统并发能力的方式,方法论上主要有两种:垂直扩展(提升单机处理能力)与水平扩展(增加服务器数量),所以软件系统中高性能带来的复杂度主要体现在两方面,一方面是单台计算机内部为了高性能带来的复杂度;另一方面是多台计算机集群为了高性能带来的复杂度。
垂直扩展
- 增强单机硬件性能,例如:增加CPU核数如32核,升级更好的网卡如万兆,升级更好的硬盘如SSD,扩充硬盘容量如2T,扩充系统内存如128G;
- 提升单机架构性能,例如:使用Cache来减少IO次数,使用异步来增加单服务吞吐量,使用无锁数据结构来减少响应时间,使用多线程来提升业务处理效率;
水平扩展
- 功能分解:基于功能将系统分解为更小的子系统
- 多实例副本:同一组件重复部署到多台不同的服务器
- 数据分割:在每台机器上都只部署一部分数据如:缓存一致性hash算法
复杂度来源:高可用
可用性是指系统无中断地执行其功能的能力。
系统高可用方案:
- 单点冗余做故障转移
- 服务熔断做服务降级
- 限流
高性能增加机器目的在于“扩展”处理性能;高可用增加机器目的在于“冗余”处理单元。而高可用带来的系统复杂度主要来源于「冗余」,因为冗余就会涉及到服务状态判断、故障转移策略、任务分配策略、数据一致性问题等。
备份的分类
冷备:系统没启动,如离线直接拷贝数据库文件。
温备:系统启动,但是没法接管业务,如在数据库运行时加全局读锁然后备份数据。
热备:系统启动,随时可以接管业务,如数据库的主从同步。
计算高可用
计算是指无论在哪台机器上进行计算(执行业务逻辑),同样的算法和输入数据,产出的结果都是一样的。
计算高可用的难点在于,引入了任务分配器,任务分配器本身也存在高可用问题
存储高可用
存储高可用主要方案就是将相同数据存在在不同机器上做数据冗余,数据存储在不同机器上就一定会出现数据不一致的情况。
存储高可用的难点不在于如何备份数据,而在于如何减少或者规避数据不一致对业务造成的影响。

高可用状态决策
无论是计算高可用还是存储高可用,其基础都是“状态决策”,即系统需要能够判断当前的状态是正常还是异常。
- 独裁式:独裁式的决策方式不会出现决策混乱的问题,因为只有一个决策者。但是他本身存也存在单点状态问题,所以会陷入死循环。
- 协商式:协商式决策指的是两个独立的个体通过交流信息,然后根据规则进行决策,最常用的协商式决策就是主备决策。存在两个个体断线的情况,一单断线,系统就无法进行协商。
- 民主式:民主式决策指的是多个独立的个体通过投票的方式来进行状态决策。例如,ZooKeeper 集群在选举 leader 时就是采用这种方式。缺点主要是算法复杂,且存在脑裂情况。
可扩展性
可扩展性是指,系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或者仅需要少量修改就可以支持,无须整个系统重构或者重建。
可扩展设计方法论主要就是"分层"和"抽象":
- 提炼出“变化层”和“稳定层”,将不变的部分封装在一个独立的“稳定层”,将“变化”封装在一个“变化层”(也叫“适配层”)。这种方案的核心思想是通过变化层来隔离变化。

- 提炼出“抽象层”和“实现层”,这种方案的核心思想就是通过实现层来封装变化,典型的实践就是设计模式和规则引擎。
可扩展性具体实现方案:
使用面向对象思想、设计模式、服务分层、微服务化、基于消息的事件总线等。
设计模式的核心是封装变化、隔离可变性
可扩展性设计原则:
- 2年原则:只预测 2 年内的可能变化,不要试图预测 5 年甚至 10 年后的变化。
- 1 写 2 抄 3 重构原则:事不过三,三则重构。
成本
低成本是架构设计中需要考虑一个约束条件,但不会是首要目标。低成本本质上是与高性能和高可用冲突的,当无法设计出满足成本要求的方案,就只能协调并调整成本目标。
降低成本的常用方法:
- 引入新技术。主要复杂度在于需要去熟悉新技术,并且将新技术与已有技术结合;一般中小型公司基本采用该方式达到目标。
- 开创一个全新技术领域。主要复杂度在于需要去创造全新的理念和技术,并且与旧技术相比,需要有质的飞跃,复杂度更高;一般大公司拥有更多的资源、技术实力会采用该方式来达到低成本的目标。
安全
安全是一个庞大而又复杂的技术领域,一旦出问题,对业务和企业形象影响非常大。从技术的角度来讲,包括:
- 功能安全-“防小偷”,减少系统潜在的缺陷,阻止黑客破坏行为,常见的 XSS 攻击、CSRF 攻击、SQL 注入、Windows 漏洞、密码破解等;
- 架构安全-“防强盗”,保护系统不受恶意访问和攻击,保护系统的重要数据不被窃取。由于是蓄意破坏系统,因此对影响也大得多。
安全设计的常用方法:
- 功能安全:是一个逐步完善的过程,而且往往都是在问题出现后才能有针对性的提出解决方案,与编码实现有关。
- 架构安全:传统企业主要通过防火墙实现不同区域的访问控制,功能强大、性能一般,但是成本更高。互联网企业更多地是依靠运营商或者云服务商强大的带宽和流量清洗的能力,较少自己来设计和实现。
规模
规模带来复杂度的主要原因就是“量变引起质变”,当数量超过一定的阈值后,复杂度会发生质的变化。随着业务的发展,规模带来的常见复杂度有:
- 业务功能越来越多,调用逻辑越来越复杂;
- 数据容量、类型、关联关系越来越多。

规模设计的常用方法:
- 规模问题需要与高性能、高可用、高扩展、高伸缩性统一考虑。常采用“分而治之,各个击破”的方法策略。
架构设计流程
识别复杂度
架构设计的本质目的是为了解决软件系统的复杂性,所以在我们设计架构时,首先就要分析系统的复杂性。实际上大部分场景下,复杂度只是其中的某一个,少数情况下包含其中两个。如果确实涉及多个复杂度,正确的做法是将主要的复杂度问题列出来,然后根据业务、技术、团队等综合情况进行排序,优先解决当前面临的最主要的复杂度问题。
如果复杂度不好判断,我们可以根据性能、可用性、可扩展性、安全性、成本、规模等复杂度通用纬度做排除法。
设计备选方案
架构方案设计可以从四个方面考虑,第一非功能性诉求(性能,可靠性,容错性,一致性等),第二研发成本(设计复杂性,实现复杂性,前期人力投入,后期人力投入,短期重构风险,工期要求),第三运维成本(运营工具是否完善,纳入现有运维体系的难度等),第四软硬件成本。架构师需要对已经存在的技术非常熟悉,如:高可用的主备方案、集群方案,高性能的负载均衡、多路复用,可扩展的分层、插件化等技术。
几种常见的架构设计误区
- 设计最优秀的方案:不要面向“简历”进行架构设计,而是要根据“合适”、“简单”、“演进”的架构设计原则,决策出与需求、团队、技术能力相匹配的合适方案。
- 只做一个方案:一个方案容易陷入思考问题片面、自我坚持的认知陷阱。
- 备选方案过于详细:备选方案过于详细会导致耗费了大量的时间和精力;将注意力集中到细节中,忽略了整体的技术设计。
备选方案设计的注意事项
- 备选方案不要过于详细。备选阶段解决的是技术选型问题,而不是技术细节。
- 备选方案的数量以 3~5个为最佳。
- 备选方案的技术差异要明显。
- 备选方案不要只局限于已经熟悉的技术。
常用备选方案
- 直接使用商业化软件,如上云,性能、HA、伸缩性都有保证。
- 直接使用开源产品,成本低,但是出现问题排查难度高。
- 直接自研,成本高,但是解决问题快。
- 基于开源方案做二次开发。
评估和选择备选方案
列出我们需要关注的质量属性点,然后分别从这些质量属性的维度去评估每个方案,再综合挑选适合当时情况的最优方案。
360 度环评表:
详细方案设计
简单来说,详细方案设计就是将方案涉及的关键技术细节给确定下来。
- 假如我们确定使用 Elasticsearch 来做全文搜索,那么就需要确定 Elasticsearch 的索引是按照业务划分,还是一个大索引就可以了;副本数量是 2 个、3 个还是 4 个,集群节点数量是 3 个还是 6 个等。
- 假如我们确定使用 MySQL 分库分表,那么就需要确定哪些表要分库分表,按照什么维度来分库分表,分库分表后联合查询怎么处理等。
- 假如我们确定引入 Nginx 来做负载均衡,那么 Nginx 的主备怎么做,Nginx 的负载均衡策略用哪个(权重分配?轮询?ip_hash?)等。
为了保证所设计架构的可行性,我们可以采用以下方式进行设计:
- 架构师不但要进行备选方案设计和选型,还需要对备选方案的关键细节有较深入的理解。
- 通过分步骤、分阶段、分系统等方式,尽量降低方案复杂度。
- 如果方案本身就很复杂,那就采取设计团队的方式来进行设计,汇集大家的智慧和经验,防止只有 1~2 个架构师可能出现的思维盲点或者经验盲区。
边栏推荐
- 05-GuliMall VirtualBox给虚拟机设置固定IP
- Writing a new app with swift5 requires some considerations
- 后台运行程序方法
- Exception: Unexpected end of ZLIB input stream
- Boyun was selected as the representative manufacturer of Gartner China cloud management tool market guide
- 【成像】【7】太赫兹光学——光学元件和子系统
- 阿里云国际版ECS云服务器欠费会自动释放吗?
- AcWing 3652. 最大连续子序列 动态规划
- Gee (6): set the number of decimal places reserved for the calculated value / image
- The most points on a straight line
猜你喜欢

小程序畢設作品之微信評選投票小程序畢業設計(5)任務書

MIPI CSI、DSI、UFS、C-PHY、D-PHY、M-PHY概念理解
![[imaging] [8] terahertz optics - beam coupling, high-order Gaussian beam model](/img/b7/1db4c5c27994b909a2033e388c9181.jpg)
[imaging] [8] terahertz optics - beam coupling, high-order Gaussian beam model
![[applet] attribute description and example of input box (text + code)](/img/70/b28518d61225f01ec369c0dd7f442e.png)
[applet] attribute description and example of input box (text + code)

2022年R2移动式压力容器充装试题及答案
![[C language] printf formatted output and modifier summary](/img/ee/67e393f364d2565b9b7f297c80c8fb.png)
[C language] printf formatted output and modifier summary

Vulnhub-DC8学习笔记

2022 questions and answers of safety management personnel operation examination of hazardous chemical business units

Language AI originally knew whether his answer was correct! New research in Berkeley and other universities is hot, netizen: dangerous, dangerous, dangerous

Operation of simulated examination platform for 2022 G2 boiler stoker examination
随机推荐
综合评价方法
Failure of CUDA installation nsight visual studio edition failed
[C language] printf formatted output and modifier summary
vivado里那些看不懂的约束语句
Exception: Unexpected end of ZLIB input stream
C#使用Marshal.SizeOf计算结构体大小返回错误
Preparation for the computer test of Baosteel 15: a master of string processing
Full resolution of the use of go native plug-ins
2022t elevator repair operation certificate examination questions and online simulation examination
Deutsche Bank listed on the world Hong Kong Stock Exchange: with a market value of HK $3.9 billion, Shaanxi Automobile Group is the major shareholder
The difference between arrayslist and LinkedList
Wechat selection and voting of finished works of applet graduation project (7) mid term inspection report
首届京东科技合作伙伴大会召开,博云携手京东科技共创产业数字化新增长
STM32应用开发实践教程:具备交互功能的人机界面应用开发
JVM内存模型
函数栈帧(值得收藏)
06 gulimall basic crud function creation
RMAN详细教程(一) —— 基本命令代码
C library function - sscanf() usage
Vulnhub-DC8学习笔记