一、什么是架构
1、系统与子系统
系统泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。它的意思是“总体”、“整体”或“联盟”。
子系统是由一群有关联的个体所组成的系统,多半会是更大系统中的一部分。
系统与子系统样例:
2、模块与组件
模块是一套一致而互相有紧密关连的软件组织。它分别包含了程序和数据结构两部分。现代软件开发往往利用模块作为合成的单位。模块的接口表达了由该模块提供的功能和调用它时所需的元素。模块是可能分开被编写的单位。
组件指自包含的、可编程的、可重用的、与语言无关的软件单元。
模块与组件样例:
3、架构与框架
框架通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。
架构指软件系统的“基础结构”,创造这些基础结构的准则,以及对这些结构的描述。
框架与架构样例:
4、重新定义架构
软件架构指软件系统的顶层结构,它定义了系统由哪些角色(Role)组成,角色之间的关系(Relation)和运作规则(Rule)。
5、分层架构与架构分层
分层架构是一种可扩展架构模式,架构分层是指架构是自顶向下,逐步细化。重点再后两个字,分层架构,首先是一个架构,这个架构为了扩展,进行了分层;而架构分层,首先是分层,就是对于总体业务,子业务分别进行架构设计。
架构分层和分层架构如下图所示。
在4R架构,可以站在不同的视角处理不同的问题,例如站在架构师的视角,可以确定层级,拆解角色,定义关系,设计规则;然后根据上述内容,需要输出对应的架构文档;同样的视角,我们在学习开源框架时,就应该自顶向下学习,该框架中有哪些角色,各个角色之间有什么关系,其运作规则是怎样的。
二、如何画好架构图
1、4+1 架构视图
历史:1995 年,Philippe Kruchten 在《IEEE Software》上发表了题为《The 4+1 View Model of Architecture》的论文,引起了业界的极大关注,并最终被 RUP 采纳。
逻辑视图:系统提供给用户的功能,对应 UML的 class 和 state diagrams。
处理视图:系统的处理过程,对应 UML 的sequence 和 activity diagrams。
开发视图:程序员角度看系统的逻辑组成,对应 UML 的 package diagrams。
物理视图:系统工程师角度看系统的物理组成,对应 UML 的 deployment diagrams。
场景视图:用户角度看系统需要实现的需求,对应 UML 的 use case diagrams。
但是国内现在很少有用4+1视图的,因为现在基本上都已经是微服务,4+1 视图很难用一个架构图表达各个关系方所关切的问题,并且 4+1 视图需要绑定 UML 图,UML 画架构图看起来非常丑且不专业,还有 4+1 视图的逻辑视图、开发视图、处理视图比较容易混淆,在一些特定场景下,各方不能统一意见。
2、大厂常见架构图介绍及画法
在互联网大厂中,主要有业务架构、客户端架构/前端架构、后端架构/系统架构、应用架构、部署架构。
(1)业务架构
描述系统对用户提供了什么业务功能,类似于 4+1 视图的场景视图。
使用场景:产品人员规划业务;给高 P 汇报业务;给新员工培训业务。
画图技巧:通过不同颜色来标识业务状态;业务分组管理
业务架构图示例:以微信为例:
(2)客户端架构、前端架构
客户端和前端的领域逻辑架构,类似于4+1 视图的逻辑视图。
使用场景:整体架构设计;架构培训。
画图技巧:通过不同颜色来标识不同角色;通过连接线来表示关系
其中前端和客户端,没有复杂的业务,主要是提供视图信息,所以客户端和前端都是按照模块进行划分。
(3)系统架构
后端的逻辑架构,又叫“后端架构”、“技术架构”。
使用场景:整体架构设计;架构培训。
画图技巧:通过不同颜色来标识不同角色;通过连接线来表示关系;
简单的系统架构,可以用一张架构图搞定
复杂的系统架构,可以使用两张图片,一张表示各个组件,一张表示各组件的关系:
(4)应用架构
描述后端系统由哪些应用组成。
使用场景:项目开发、测试;部署发布;子域架构设计。
画图技巧:通过不同颜色来标识不同角色;通过连接线来表示关系。
以 mongo 和 hbase 为例的应用架构如下所示:
应用架构和系统架构/后端架构有时候比较类似,应用架构的侧重点是后端服务有哪些应用组成,而后端架构/系统架构侧重点是所有的应用和组件,那么对于我们的业务系统来说,应用架构就是微服务的拆分,有哪些业务微服务组成,而系统架构除了我们的应用服务外,还应该有我们引用的组件,例如缓存、存储、MQ、配置中信、注册中心等等。但是在另外的一些场景,例如开源组件中,应用架构和系统架构其实是对等的。
(5)部署架构
描述后端系统具体如何部署的,对应 4+1 视图的物理视图。
使用场景:总体架构设计;运维规划和优化。
画图技巧:用图标代替区块
3、系统序列图
因为架构图只是表现了 4R中的 Role(角色) 和 Relation(关系),但是并不能表现运作规则 Rule(规则),因此核心功能需要画序列图。系统序列图用 UML 序列图来画。
三、架构设计方法论
1、常见的架构设计方法论
(1)方法论的意义
首先我们做架构要有自己的架构设计方法论,例如面向模式、面向风险、面向复杂度、DDD等等,而不能不做分析直接面向大厂、面向老板、面向新技术做架构,合适自己的才是最好的。
(2)面向模式
面向模式主要是指 《面向模式的架构设计》 丛书,总共有5本,是架构设计领域的 ”设计模式“,其核心思想是应用经过验证的架构模式,例如 MVC、Reactor等。
但是面向模式架构也有很大的问题,其中的架构模式太庞大,高度抽象且比较理论化,很难自己从中选择一个适合自己的架构,并且很难落地。
(3)面向风险
风险驱动的架构设计核心思想是根据系统风险大小来设计软件架构。
但是风险是一种概率预判,一切皆有可能
(4)DDD
领域驱动设计,在全世界比较火,但是在国内并不是很火。DDD是可扩展架构的设计技巧,不能算是架构设计方法论;DDD兼顾架构设计和方案设计。
但是DDD敏捷架构不关注存储、计算、部署等内容。
2、面向复杂度的架构设计
(1)为什么做架构
首先我们要明白为什么要做架构,因为架构重要因此要做?为了提升开发效率和促进业务发展?公司流程要求?为了高性能、高可用、高扩展?其实都不太对。
架构设计的本质是为了降低软件的复杂度;然后通过分析系统需求找到系统复杂的地方,然后进行设计。
复杂度来源:高性能、高可用、高扩展、安全、成本等等
落地方案:找到复杂度后,要使用落地方案来解决,例如高性能对应的分不分表、缓存、集群等,高可用对应的集群、分片等,高扩展对应的微服务等,包括DDD、异地多活等
(2)面向复杂度设计环
面向复杂度的设计,从最原始的需求进行分析,对于不清晰的节点进行澄清,然后分析复杂度并对复杂度进行拆解,拆解完成后,设计架构,同时要有备选架构,并且需要做取舍,按照 4R 架构进行取舍,最终满足业务需求。
四、如何做好架构
1、架构设计三原则
合适原则:合适自己的才是最好的,合适优先于行业领先。
简单原则:在合适原则的基础上,简单的架构要优于复杂的架构。
演化原则:首先满足当前业务,然后再迭代优化,优化优于一步到位。
无论是大公司还是小公司,架构设计都应该满足架构设计三原则,目标太大,就是空中楼阁,很难实现,同时架构设计本质上是 ”精英设计“,人多反而会造成相互指责、推诿、扯皮的问题。同时技术上的高大上是没有意义的,符合业务和团队的才是最好的,同时架构的质量也遵循木桶原理,最短的短板决定了架构的质量。
2、架构设计三原则应用
设计出来的架构要满足当时的业务需要,符合团队和技术的能力水平(合适原则);先按照简单的方式来设计架构,然后不断地在实际应用过程中迭代优化(简单原则);当业务发生变化时,架构要扩展、重构,甚至重写(演化原则)。
在面向复杂度的架构设计中,架构设计三原则遍布于判断、拆解、取舍这几个阶段,每一个阶段都要基于架构设计三原则进行判断。
常见的设计原则的判断维度:业务、团队、技术。
业务:业务当前的量级、业务发展速度、业务发展态势
团队:团队规模、团队能力水平、投入的资源
技术:已有技术体系、当前技术能力、技术成熟度
五、架构设计样例
如果做一个学生管理系统,怎么做架构呢?
1、学校做学生管理系统
复杂度分析,高性能、高可用、高扩展、成本、安全?要分析复杂度在哪里,那么对于一个学校的学生管理系统来说,由于人员不多且宕机影响不大,因此高性能和高可用不是其复杂点,但是对于学校来说,业务可能复杂,同时数据安全要保证,不能使数据全部丢失,那么对于以上两个复杂点,就可以作为架构的切入点,例如业务复杂,就需要做服务拆分,数据不能丢失就需要做数据库的主备。
对于上述复杂度分析后,就可以设计出其架构,由于业务比较简单,因此下图既是业务架构,又是系统架构,还是应用架构,同时还是部署架构
取舍:
那么上述的架构方案是否合理呢?这就要使用架构设计三原则(合适、简单、演进)进行取舍,首先就是合适,角度有:团队的技术水平、方案成本、开发周期、方案认可度等。
合适原则:符合团队的技术水平和技术积累;开发成本低;系统运维成本低
简单原则:不进行系统拆分;部署运维简单;没有微服务,不需要微服务基础设施
演化原则:一次性交付,无需考虑太多后期演化;学校的学生数量不会有很大的变化,系统架构可以使用多年。
具体取舍样例:
如果团队成员对mongoDB很熟悉,但是对MySQL不是很熟悉,那么存储就可以换为MongoDB,同理,熟悉Oracle也是一种取舍因素。或者由于已有DNS,因此就可以不使用Nginx,而直接使用已有DNS即可。
2、创业公司做学生管理系统
对于创业公司,除了原有的复杂度需求外,还要考虑高可用、高性能,同时是否可以隔离各个学校,避免相互之间影响。
高性能?全国那么多高校,以最终会有三千个学校买这个服务,一个学校10万人,那么整体用户量就是三个亿
高可用?是否要对全国高校分为东西南北四个大区
高扩展?全国这么多高校,需求肯定各种变化,是否需要可扩展
数据安全?高校之间要隔离,数据要保证安全
针对于以上的几个点,是否要采纳,是需要根据架构设计三原则来进行取舍的:
高性能?对于一个创业公司来说,上去肯定不会直接就是3亿用户,也有可能最终都没有做起来,因此应该遵循演进原则,先按照十几家学校进行设计,后续随着接入学校变多,在进行改造
高可用?原理同高性能的设计,要遵循演进原则和简单原则
高扩展?这个是必须的,因为这个项目一开始就是要面向全国高校的,因此一开始就要做可扩展的设计。遵循了合适原则
数据安全?这个也是必须的,对不同学校的数据进行隔离,同时保证数据安全。遵循了合适原则。
具体架构设计:
根据上面的分析,需要考虑可扩展和数据安全。
方案一,服务不隔离,数据隔离;数据隔离采用数据库隔离,每个学校单独建一个库;数据安全使用数据库主备 + 每日备份
方案二,服务隔离,数据隔离,服务隔离采用docker隔离,数据隔离采用数据库主备 + 每日备份
方案三,双机房数据隔离。服务不隔离,在不同的机房部署相同的集群,但是数据隔离,不同的机房让不同的学校使用。
方案四,双机房服务数据双隔离。在不同的机房对应不同的区域,对于区域内,对服务个数据进行隔离。
架构选择:
最终选择架构一,因为其比较简单,符合简单原则,同时也做到了可扩展和数据隔离,符合合适原则,方案二,可以做到十几家学校后,再演进为方案二,对于方案三和方案四,可以随着进入数量的增多,再进行改造,这也符合演进原则。
架构的核心场景:对于数据如何隔离
首先DBA需要创建数据库,运维创建域名,添加Nginx配置,运行后台需要创建学校,配置信息添加到服务器,运营人员添加学校的管理员
3、教育部做一个学生管理系统
这里和创业公司最大的区别就是,教育部是行政机构,快速的就要接入全国高校,因此从一开始,就需要按照高性能、高可用、高扩展来设计,那么对于用户数量的预估,同时对于全国高校分区处理,这些都是必须的,如果此时进行架构选型,就需要选择架构四。