架构学习入门

最近了解了一下架构这个东西,从最开始的一脸懵逼到越看越迷再到慢慢摸清头绪,现在回过头来进行一个总结。回顾一下什么是架构、架构有哪些分类、应用架构的演进过程。

基本概念理解

在准确理解架构这个概念之前,先了解一些基本的概念。

系统与子系统

首先来看维基百科对系统的定义:

系统:泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体

从这里面可以提炼出一个系统的几个关键内容:

  • 关联:系统是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个系统。 例如,把一个发动机和一台电脑放在一起不能称之为一个系统,把发动机、底盘、轮胎、车架组合起来才能成为一台汽车。
  • 规则:系统内的个体需要按照指定的规则运作,而不是单个个体各自为政。 例如,汽车发动机负责产生动力,然后通过变速器和传动轴,将动力输出到车轮上,从而驱动汽车前进。
  • 能力:系统能力与个体能力有本质的差别,系统能力不是个体能力之和,而是产生了新的能力。 例如,汽车能够载重前进,而发动机、变速器、传动轴、车轮本身都不具备这样的能力。

接着来看子系统的定义:

子系统也是由一群有关联的个体所组成的系统,多半会是更大系统中的一部分。

其实子系统的定义和系统定义是一样的,只是观察的角度有差异,一个系统可能是另外一个更大系统的子系统。

按照这个定义,系统和子系统比较容易理解。我们以微信为例来做一个分析。

微信本身是一个系统,包含聊天、登录、支付、朋友圈等子系统。

朋友圈这个系统又包括动态、评论、点赞等子系统。

评论这个系统可能又包括防刷子系统、审核子系统、发布子系统、存储子系统。

(评论审核子系统不再包含业务意义上的子系统,而是包括各个模块或者组件,这些模块或者组件本身也是另外一个维度上的系统。

例如,MySQL、Redis 等是存储系统,但不是业务子系统。)

中间件

首先还是来看维基百科对中间件的定义:

中间件(Middleware),又译中介层,是一类提供系统软件和应用软件之间连接、便于软件各部件之间沟通的软件,应用软件可以借助中间件在不同的技术架构之间共享信息与资源。中间件位于客户机服务器的操作系统之上,管理着计算资源和网络通信。

单纯听定义比较抽象,下面举一个比较生动的例子来类比一下:

我开了一家炸鸡店(业务端),然而周边有太多屠鸡场(底层),为了成本我肯定想一个个比价,再综合质量挑选一家屠鸡场合作(适配不同底层逻辑)。由于市场变化,合作一段时间后,或许性价比最高的屠鸡场就不是我最开始选的了,我又要重新和另一家屠鸡场合作,进货方式、交易方式等等全都要重来一套(重新适配)。

然而我只想好好做炸鸡,有性价比高的肉送来就行。于是我找到了一个专门整合屠鸡场资源的第三方代理(中间件),跟他谈好价格和质量后(统一接口),从今天开始,我就只需要给代理钱,然后拿肉就行。代理负责保证肉的质量,至于如何根据实际性价比,选择不同的屠鸡场,那就是代理做的事了。

模块与组件

先给出定义:

模块是指由数个基础功能组件组成特定功能组件,可用来组成具完整功能之系统、设备或程序。模块通常都会具有相同的制程或逻辑,更改其组成组件可调适其功能或用途。

软件组件定义为自包含的、可编程的、可重用的、与语言无关软件单元,软件组件可以很容易被用于组装应用程序中。

看完之后估计还是莫名其妙,而且日常也会听到这样的说法:

- MySQL 组件主要负责存储数据,而 ElasticSearch 模块主要负责数据搜索。

- 我们有安全加密组件、有审核组件。

- App 的下载模块使用了第三方的组件。

总觉得听懂了,但好像又没完全懂。

其实,模块和组件都是系统的组成部分,只是从不同的角度拆分系统而已。

逻辑的角度来拆分系统后,得到的单元就是“模块”;

物理的角度来拆分系统后,得到的单元就是“组件”。

划分模块的主要目的是职责分离;

划分组件的主要目的是单元复用。

我们用一个最简单的订单管理系统为例:

将这个系统从逻辑的角度来拆分,就得到了各种模块,包括“订单查询模块”“订单添加模块”“登录注册模块”;

将这个系统从物理的角度来拆分,得到的就是各种组件,包括Web 服务器、Apache服务器、MySQL数据库;

其实,“组件”的英文component也可翻译成中文的“零件”一词,“零件”更容易理解一些,“零件”是一个物理的概念,并且具备“独立且可替换”的特点。

就比如我们将Web服务器替换为APP终端,将Apache服务器换做IIS,数据库用SQL Server,所有的物理组件虽然都变了,但系统的模块没有变。

架构、结构、框架

架构提供了系统最高层次的设计方案,以确保系统满足期望的目标

比如我们常说

- 好的建筑应该美观、坚固、实用

- 好的计算机应用应该实用、好维护、可靠、性价比高

这就是对事物、系统的一个期望,架构设计就是为了满足这种期望

结构是指组成系统的具体组件及其关系,架构中包含结构的初步描述和决策

架构包含系统的一组基本结构,每种结构都由各种类型的部件及其关系构成;

架构描述了这些部件的组合、相互调用参照、通信以及其他动态交互

好了,(看不懂)的定义说完了,下面还是用例子理解:

(架构这个词最初是建筑上用的,所以我们用桥梁设计为例子进行说明)

桥梁设计有两个方面:架构设计和结构设计

桥梁的架构设计: 为了满足桥梁的各方面需求所进行的最抽象、最全局的设计,可以用草图描述,架构决定了桥梁的基本组成结构体系。常见的桥梁架构见下面的图片

架构方案决定了桥梁的基本组成结构体系,比如我们提到斜拉桥和悬索桥,即使不知道具体的建筑方式、用料等信息,但也能从草图上知道是两种不同的桥梁类型

所以当我们说一座桥采用了斜拉桥的架构,就确定了这座桥一定会包含:索塔、主梁、斜拉索等基本组件;

而桥梁结构设计就是根据架构方案设计出具体的各个组件的细节

如斜拉桥的索塔需要几个、每个有多高、承重多少;主梁长度、宽度、形状、个数;斜拉索的数量、距离、材质、直径;各个组件之间的接口细节。这些细节对于每座桥来说都不同。

所以说,世界上不可能有完全相同的两座桥梁,但不论最终桥梁长宽、材质、形态如何变化,万变不离其宗,宗就是指架构

那么架构与结构是什么样的关系:

架构是抽象的,体现了高层全局的决策,架构包含了结构的初步描述和决策

结构是具体有形的,体现决策的贯彻,相同架构的系统,具体结构允许有差异

需要注意的是:架构是系统设计中最稳定的部分,也意味着,系统架构如果想变更,几乎等于对系统重建

框架这个词多用于软件设计中:

软件框架(Software framework)
通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。

可以理解为,框架是一种规范,因为在长期的设计实践中,发现对于某种场景或者需求,使用这样一套架构就比较有效,长此以往,这种架构就变成了一种规范,也就是框架。框架关注的是“规范”,架构关注的是“结构”

封装与接口

封装(Encapsulation)在面向对象编程方法中指,一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法。同时,它也是一种防止外界调用端口,去访问对象内部实现细节的手段,封装被视为是面向对象的四项原则之一。

写代码的肯定都知道函数的调用,其实函数本身就可以看做是一段代码的封装,通过固定的格式去使用,那么那个固定的格式就是这个函数的接口

接口泛指实体把自己提供给外界的一种抽象化物(可以为另一实体),用以由内部操作分离出外部沟通方法,使其能被内部修改而不影响外界其他实体与其交互的方式。

接口的话,比如电脑和人之间的接口就是屏幕,通过屏幕,人能够获取计算机的信息,并通过屏幕和计算机交互

软件技术架构

了解了一些基本的概念后,我们回到本篇的主题——架构上。

为什么要有架构

架构这个概念是随着计算机、软件的发展才出现的,那么没有架构行不行,为什么要有架构?

我们可以用两张图来做一个感受:

左边这张图是1960年一段计算三角形面积的程序代码,运行这段代码就能够实现求解三角形的面积的功能。

右边这张图是2015年,安卓4.4的架构图,当时的安卓系统代码量超过1亿行

从这两张图就可以看出来,最早计算机发明的时候不需要架构,随着发展,软件越来越复杂,如果没有架构,1亿行代码,从哪开始写???可以说,没有一个框架、没有一个组织结构的话,从事不了如此大型的软件开发。

结论:软件架构本质上就是为了解决软件的复杂性问题。

软件架构定义

这里补充下软件架构的定义,用于参考理解:

ISO:

Fundamental concepts or properties of a system in its environment embodied in its elements, relationships, and in the principles of its design and evolution.

Software Architecture in Practice(3rd):

The software architecture of a system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both.

大致意思就是说,软件架构是软件的某种结构、涉及到元素以及元素之间的关系、涉及到软件的基础概念和属性、包含一些设计和演化原则

其实还是很不好理解,那就继续向下看吧

软件架构在IT项目中的位置角色

那么软件架构在IT项目中到底是什么样的位置和角色呢?

从上面这张图可以做个简单的了解:

软件架构是要实现的业务目标和目标系统之间的中间产物、联系纽带;

为了实现业务目标设计了某种架构,基于这种架构实现了系统;

系统遵从我们的架构设计,同时我们的架构也满足业务目标;

对一个项目来说来说就是,为了实现业务目而做了一个系统,这个系统满足业务目标。

知道了软件架构的必要性、在项目中的位置,那么软件架构到底是什么?

软件架构直观理解

直观来说,软件架构就是满足干系人关键诉求的一系列宏观决策

比如在做架构时,经常要考虑下面一些问题:

C/S还是B/S?

单体还是微服务?

用什么OS?数据库?Web APP Server?

用什么开发语言?

三层还是四层?

用不用缓存?

如何避免单点故障?

如何方便运维?

RPC还是 WebAPI?

把这些问题都想清楚了,似乎就完成了软件的架构设计(其实不准确)。我们把上面的这些问题进行归纳,把影响软件架构决策的问题归为4种:

功能需求: 项目是用来作什么的,业务是什么

质量属性: 软件的一些质量要求,包括可用性、可测试性、易维护性等等

约束: 项目面临的一些现实情况(比如开发人员只会java、客户要求必须用微服务架构),与需求、质量属性无关

趋势: 架构完成后,不能太陈旧、落后、原始,要考虑当下的趋势和软件长期演化过程中的发展

可以说,对上面4个因素进行了详细全面的考虑之后,就能够做出一个比较合适的软件架构

补充:干系人、软件质量属性

这里补充两点内容,便于阅读:

1)干系人:积极参与项目实施或者在项目完成后其利益可能受积极或消极影响的个人或组织

上面的每一个都代表若干人

购买者: 其实就是客户,但往往是客户中的决策层。可能不用系统

使用者: 真正使用系统的

开发者: 实现软件系统的人,不仅包括开发团队,还包括项目经理、部门经理,组织的技术管理者

维护者: 负责系统运维的人,往往是容易被忽略的

2)软件的质量属性:

架构的评价

进行架构设计的时候,如何评价一个架构好还是不好?这里面可能有很多不同的看法,例如:

越经济越好:开发起来省力、效率高

越先进越好:流行什么用什么

越超前越好:尽管不成熟,先用上

越成熟越好:尽量用现有的成熟技术

越稳定越好:不要重大急,这样我运维就能安心工作

越传统越好:越传统越熟悉

越简单越好:架构越简单,理解越容易

但说到底,架构是一个平衡多方面利益诉求的结果,不能从一个单一维度评价

比如我设计了一个架构,满足质量属性要求、满足约束、满足了业务需求、成本也低,虽然有点传统,但这个业务场景下适用,不能说不是个好的架构。

程序员与架构师的区别

在一个软件系统的设计实现过程中,不仅仅是架构师去设计,还要靠程序员去实现,那么两者之间的区别是什么?下面从几个不同角度去理解一下:

1)从考虑问题的视角区分

在整个项目的开发过程中,架构师往往要考虑的更多,一方面要看到技术的发展。,一方面还要看到整个行业的发展,还要和项目中不同干系人沟通、考虑项目整个生命周期的使用情况,现有的基础设施是什么等等,而程序员更专注于做好眼下的这个软件。可以说,架构师的视角更加宽泛,程序员集中在软件本身功能的实现上。

另外,设计一个软件系统,既有功能需求,也有质量属性约束

软件的业务逻辑侧重功能需求;软件结构和关系侧重质量属性和约束

在开发的时候:

程序员侧重功能需求;架构师侧重质量属性和约束,同时也要考虑功能需求

对于干系人来说:

功能需求和使用者关系更紧密;质量属性约束和软件的购买者及开发运维者关系更密切

用下面这张图来说,就是:

架构师站在右边向左看;程序员站在左边向右看。架构师需要多考虑到功能需求,考虑到开发运维者的工作,当然

不同的项目也要看实际情况,如果程序员特别厉害,想多做一点架构方面的工作也没有问题。

2)从输入输出上

程序员:在项目经理监督下,按照规格写出程序,对规格负责

架构师:承受多方压力,大多数时候要求是相冲突的,架构师和所有人沟通,得到一个折中的,满足大部分人要求的方案

3)从工作流程上看

程序员基本上是线性过程,根据设计流程一步步完成工作。当然也会有反复,比如在测试的时候发现问题,返回去重新进行设计

架构师的工作则是要多项同步进行,可能这会在进行信息搜集,下一会就要去和不同干系人进行沟通,一边还要对资料进行分析整理,同时还要输出一个设计或者相关文档,基本上是好多事情混合在一起完成的

架构分类

知道架构是什么,在做什么之后,接下来我们通过对架构进行分类,更深入的了解一个系统的不同层面

架构从项目的不同角度可以分为:业务架构、应用架构、技术架构、数据架构、物理部署架构

那么不同的架构分别用于解决什么问题,服务于谁呢?我们可以从一个系统落地的过程中找到答案

系统落地

对于一个系统来说,开发人员去开发系统,机器为系统运行提供物理设备

对于负责开发的人来说,怕的是业务太复杂,代码逻辑太乱,超出他能理解的范畴,系统无法维护。

因此开发的需求是系统整体概念清晰,容易理解,方便扩展

对于负责运行的机器来说,怕的是业务并发量太大,系统核心资源不够用(如数据库连接)。

它希望在业务量增加时,系统能够支持水平扩展,支持硬件容错(如避免单点故障)

不同的架构其实就是在解决这些痛点。

2架构的使用

开发的痛点主要由业务架构应用架构解决:

业务架构从概念层面帮助开发理解系统。(动态的包括业务流程 / 节点 / 输入输出,静态的包括业务域 / 业务模块 / 单据模型)

应用架构从逻辑层面帮助开发落地的系统(应用种类 / 应用形式 / 数据交互关系 / 交互方式等),使得整个系统逻辑上容易理解。(如SOA架构)

机器的痛点主要由技术架构解决,如技术平台选型(操作系统 / 中间件 / 设备等),部署上希望支持多机房,水平扩展,无单点等。

用打仗来进行比喻的话,就是:

业务架构是战略(整体目标),应用架构是战术(如何实现),技术架构是装备(用什么实现)

其中应用架构承上启下,一方面承接业务架构的落地,另一方面影响技术选型。

熟悉业务,形成业务架构,根据业务架构,做出相应的应用架构,最后技术架构落地实施。

强调一下,系统是人的系统,架构首先是为人服务的,业务概念清晰、应用逻辑合理、人好理解是第一位的(即系统有序度高)。

现在大家讨论更多的是技术架构,如高并发设计,分布式事务处理等,只是因为这个不需要业务上下文背景,比较好相互沟通。

具体架构设计时,首先要关注业务架构和应用架构,这个架构新手要特别注意。

下面这张图展示了不同架构之间的关系,可以看出,首先需要确定的是业务架构(顶层设计),根据业务架构确定每个应用的架构,之后根据业务和应用架构情况,就能确定数据架构和技术架构,那么相应的物理架构也就可以确定了。

接下来分别看看各种架构的具体内容

业务架构(俯视架构)

业务架构指的是:使用一套方法论对产品(项目)所涉及到的业务进行业务边界划分,简单的讲就是根据一套逻辑思路进行业务的拆分,把现实的业务转化成抽象对象。包括业务规划,业务模块、业务流程。

这张图是网上找到的京东的业务架构图。可以看到,首先它的业务被分为了几个大的板块,POP、用户板块、支付板块、财务板块,以及下面的网站、交易、订单、履约板块,还有供应链板块、商品、促销、库存等等。

在每个板块上,又有各自的业务模块,明确每一块要做什么。

除此之外,还能看到不同版块之间的联系,表示业务在不同版块之间的流通,板块与板块之间的关系。

(这一套业务架构是根据京东自身的特点衍生出来的,就比如大物流板块,因为京东是自建物流,所以要考虑商品转运、时效性。如果换做淘宝、拼多多等电商平台,就又不一样了)

可以说:

没有最优的架构,只有最合适的架构,一切系统设计原则都要以解决业务问题为最终目标, 脱离实际业务的技术情怀架构往往会给系统带入大坑,任何不基于业务做异想天开的架构都是耍流氓。

所有问题的前提要搞清楚我们今天面临的业务量有多大,增长走势是什么样,而且解决高并发的过程,一定是一个循序渐进逐步的过程。合理的架构能够提前预见业务发展1~2年为宜。这样可以付出较为合理的代价换来真正达到技术引领业务成长的效果。

应用架构(坡面架构,也叫逻辑架构图)

顺着业务架构,接下来简单介绍下应用架构(真的是很简单的介绍,复杂的东西太多了,这里仅供入门了解)

应用架构是介于业务和技术之间的,将业务的运作逻辑进行细分,告诉技术我需要实现什么样的效果,所以说:

应用架构介于业务语言与技术语言之间,是对整个系统实现的总体上的架构,描述了IT系统功能和技术实现的内容。

在应用架构中,应用作为独立可部署的单元,为系统划分了明确的边界,深刻影响系统功能组织、代码开发、部署和运维等各方面。这里所谓应用就是各个逻辑模块或者子系统。

下面还是以两个简单的例子来理解:

1)假如我们已经通过业务架构划清了系统要做什么,比如有简单业务:满足用户对信息的查询;有复杂的业务,用户可以通过系统进行采购交易

那么这些业务具体以什么样的逻辑完成,就是应用架构进行设计的

比如最简单的信息查询,只需要设计三层结构,最上层与用户交互,用于接收查询请求以及展示数据;中间层进行数据处理,将用户请求发送至数据库,将数据库的结果返回给用户;最底层数据库存放所有的数据,拿到查询请求后就返回相应的数据。通过这样的逻辑结构,接下来的技术架构就知道我要实现用户的交互、信息的处理、数据库的查询等功能,那么就可以去考虑使用那些具体的技术,从而完成技术架构

2)对于较为复杂的系统,基本逻辑也是相似的,最外层的渠道展示与那些对象交互,提供什么服务;中间具体列举了服务的类型,包括应用服务,聚合服务;最底层则展示了我希望通过使用多个数据库来实现这一过程。

有了应用架构,就能够去完成技术架构的设计,当然,反过来,技术的局限性也会要求应用架构有相应的调整。

技术架构

接下来介绍技术架构,其实根据前面的介绍,简单来说,技术架构就是将产品需求进行技术实现的手段,具体来说,技术架构的定义如下:

技术架构是确定组成应用系统实际运行的技术组件、技术组件之间的关系,以及部署到硬件的策略。

技术架构解决了如何进行纯技术层面的分层、开发框架的选择、语言选择、涉及到各自非功能性需求的技术点(安全、性能、大数据)。

还是以实际的例子来说,下面这张图左侧文字体现了前面讲的应用架构,将系统分为5层,右边就是每一层具体使用什么技术去实现每一层的功能。比如前端就有熟悉的HTML、CSS,还有JavaScript、H5等等;底层的数据存储既有像MySQL、MongoDB等技术应用;同理,接口层、中间的服务层也都给出了具体的技术使用。

通过这张图,开发人员就能够了解每一部分要做的是什么,以及怎么去做、用什么去实现功能。

数据架构

数据架构指导数据库的设计。不仅仅要考虑开发中涉及到的数据库,实体模型,也要考虑物理架构中数据存储的设计。

物理部署架构

又叫拓扑架构,包括架构部署了几个节点节点之间的关系,服务器的高可用,网路接口和协议等,决定了应用如何运行,运行的性能,可维护性,可扩展性,主要是运维工程师主要关注的对象。

总结

总体来看,首先需要熟悉业务,形成业务架构,根据业务架构,做出相应的数据架构和应用架构,最后通过技术架构落地实施。

业务架构是战略,应用架构是承上启下,一方面承接业务架构的落地,另一方面影响技术架构的选型。

应用架构演进

业务架构是生产力,应用架构是生产关系,技术架构是生产工具。业务架构决定应用架构,应用架构需要适配业务架构,并随着业务架构不断进化,同时应用架构依托技术架构最终落地。应用架构的演进大体上经历了下图的过程:单体应用–>分布式应用服务化–>微服务

单体应用

1)两层架构

单体应用中最基础的是两层架构,一层是用户表现层,将用户界面、数据访问、业务逻辑,都放在一起;另一层就是底层数据库。

这种架构只适合于系统很简单的情况。当任何一个地方发生变化时,都需要重新开发整个系统。"多层"放在一层,分工不明确耦合度高——难以适应需求变化,可维护性低、可扩展性低

假如我的系统原本提供的是查询功能,展示数据库中订单记录的所有信息,现在我想要分两部分展示,一部分只展示订单号、商品名、销售单价;另一部分只展示订单号、销售人员、订单日期。那么这种结构就需要将这个查询的逻辑重写、展示界面重新设计。

所以后来就发展出了新的三层架构模式

2)三层架构

典型的三级架构:前端(Web/手机端)+中间业务逻辑层+数据库层。

层次清晰,分工明确,每层之间耦合度低——提高了效率,适应需求变化,可维护性高,可扩展性高

3)单体应用的缺点

单体应用虽然降低了系统的耦合度,但随着发展,也逐渐暴露出一些缺点:

复杂性高: 以一个百万行级别的单体应用为例,整个项目包含的模块非常多、模块的边界模糊、 依赖关系不清晰、 代码质量参差不齐、 混乱地堆砌在一起。可想而知整个项目非常复杂。 每次修改代码都心惊胆战, 甚至添加一个简单的功能, 或者修改一个Bug都会带来隐含的缺陷。

技术债务: 随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务, 并且越积 越多。“ 不坏不修”, 这在软件开发中非常常见, 在单体应用中这种思想更甚。 已使用的系统设计或代码难以被修改,因为应用程序中的其他模块可能会以意料之外的方式使用它。

部署频率低: 随着代码的增多,构建和部署的时间也会增加。而在单体应用中, 每次功能的变更或缺陷的修复都会导致需要重新部署整个应用。全量部署的方式耗时长、 影响范围大、 风险高, 这使得单体应用项目上线部署的频率较低。 而部署频率低又导致两次发布之间会有大量的功能变更和缺陷修复,出错率比较高。

可靠性差: 某个应用Bug,例如死循环、内存溢出等, 可能会导致整个应用的崩溃。

扩展能力受限: 单体应用只能作为一个整体进行扩展,无法根据业务模块的需要进行伸缩。例如,应用中有的模块是计算密集型的,它需要强劲的CPU; 有的模块则是IO密集型的,需要更大的内存。 由于这些模块部署在一起,不得不在硬件的选择上做出妥协。

阻碍技术创新: 单体应用往往使用统一的技术平台或方案解决所有的问题, 团队中的每个成员 都必须使用相同的开发语言和框架,要想引入新框架或新技术平台会非常困难。

分布式架构

介绍分布式架构之前,前介绍一个概念:负载均衡

1)负载均衡

负载均衡(Load Balance),其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。

单体应用时,所有的读写请求均由一台服务器完成,当数据量过大,服务器因过载而宕机,整个应用崩溃。

负载均衡指:使用多个服务器(硬件设备),每个服务器分别负责各自的任务,共同分担以前一台服务器的任务

2)分布式架构

分布式架构: 对系统按照业务功能模块拆分,将各个模块服务化,变成一个分布式系统。业务模块分别部署在不同的服务器上,各个业务模块之间通过接口进行数据交互。

分布式架构正是为了实现负载均衡而进行的设计

随着业务深入,业务要求的产品功能越来越多,每个业务模块逻辑也都变得更加复杂,业务的深度和广度都增加,使得单体应用变得越来越臃肿,可维护性、灵活性逐渐降低,增加新功能开发周期越来越长,维护成本越来越高。

这时需要对系统按照业务功能模块拆分,将各个模块服务化,变成一个分布式系统。业务模块分别部署在不同的服务器上,各个业务模块之间通过接口进行数据交互。

3)分布式架构特点

分布式架构相对于单体架构来说,提供了负载均衡的能力,大大提高了系统负载能力,解决了网站高并发的需求。另外还有以下特点:

降低了耦合度: 把模块拆分,使用接口通信,降低模块之间的耦合度。

责任清晰: 把项目拆分成若干个子项目,不同的团队负责不同的子项目。

扩展方便: 增加功能时只需要再增加一个子项目,调用其他系统的接口就可以。

部署方便: 可以灵活的进行分布式部署。

缺点: 系统之间的交互要使用远程通信,接口开发增大工作量,但是利大于弊

SOA(Service-Oriented Architecture)

《微服务设计》 1.3节定义:

SOA(面向服务架构)是一种设计方法,其中包含多个服务,而服务之间通过配合最终会提供一系列功能。一个服务通常以独立的形式存在于操作系统进程中。服务之间通过网络调用,而非采用进程内调用的方式进行通信。

下面是一个SOA架构的示意图,可以看到,对于I/O接口的服务请求,通过总线上不同的服务来实现

单纯看上面的定义和图并不容易理解,下面通过两个例子说明一下什么是SOA:

1)例1

假设现我有一个数据库,一个JavaWeb(或者PHP等)的网站客户端,一个安卓app客户端,一个IOS客户端。

现在我要从这个数据库中获取注册用户列表,如果不用SOA的设计思想,那么就会这样:JavaWeb里面写一个查询方法从数据库里面查数据然后在网页显示,安卓app里面写一个查询方法查询后在app上显示,IOS同样如此。这里就会出现查询方法重叠了,这样的坏处很明显了,三个地方都有相同的业务代码,要改三个地方都要改,而且要改的一模一样。当然问题不止这一个。

于是乎出现了这样的设计思想,比如用Java(或者是其他语言皆可)单独创建一个工程部署在一台服务器上,并且写一个方法(或称函数)执行上述查询操作,然后使其他人可以通过某种途径(可以是http链接,或者是基于socket的RPC调用)访问这个方法得到返回数据,返回的数据类型是通用的json或者xml数据,就是说把这个操作封装到一个工程中去,然后暴露访问的方式,形成“服务”。比如这里就是注册用户服务,而关于注册用户的所有相关增删改查操作这个服务都会提供方法。

2)例2

上面的例子说明了一个服务是如何形成以及工作的,那么一条服务总线上可以看到有多个服务,这个如何理解?

用一个比较形象的例子:

比如最开始开了一个普通饭店,一下来了10个人,大家围成一桌开始点菜吃饭,你烧完一桌菜又来了20个人,这20个人点的菜有的和刚才10个人点的重复,当然也有不一样的,但是会出现这样一个问题,这20个人,除了小李和老王其他都不喜欢吃猪蹄,结果老王把菜点上了,最后剩下很多造成了浪费,而且因为店面人手不足的问题,如果出现一下来了好几拨人情况,会忙不过来。

某一天这个老板萌生出开自助餐的概念,甭管客人想吃什么,在饭点之前先把各式各样的菜先烧好,你来10个人也好,100个人也好,自己真正喜欢吃什么,有什么需求自己去对应的位置拿菜。

SOA架构也是类似的思想,通过将一个个服务封装好,将所有业务部署至服务总线,不同的业务调用不同的服务,通过服务的组合实现业务功能。

微服务

1)微服务

介绍完SOA的思想之后,再来看一个近些年比较流行的架构——微服务

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。

下面这张图就是单体向微服务的过度,可以看到,微服务的流程和SOA是相同的,也是把流程拆分为多个服务,根据实际情况的不同,使用不同的服务组合实现业务

可以看到微服务和SOA非常相似,微服务到底和SOA有没有关系?其实,这其中就隐藏着两种关系:

(1)微服务简化了SOA架构思想,是SOA一个离经叛道的继任者;

(2)微服务进行了SOA基因改造,成了一个新的变种;

微服务是SOA一个离经叛道的继任者, 其实这是一句赞美之词!

2)微服务与SOA对比

我们来看看微服务和SOA比起来有多么的相似,又多么的不同。

(1)微服务专注小的个体问题,形成服务,通过松耦合的通讯机制协作起来,解决更大的问题;反之,SOA一开始就专注大的协调问题,首先关注的是服务协议、规则、表述的统一性,然后才是设计足够大的独立服务,并通过流程建模,解决整体上的问题。

(2)微服务倾向于拆分,也就是将单体应用尽量拆分到一个适当的粒度,形成个人或小团队去关注独立的服务个体;但SOA不同,服务要足够的粗粒度,服务接口只是作为异构系统调用的统一手段,甚至我们可以将一个大系统作为SOA的一个构建服务而独立存在,例如前面说到的应急指挥系统的SOA架构中通讯调度系统作为一个独立的SOA服务而存在。

(3)微服务的实施模式是自底向上型:不同的小团队分配不同的微服务进行开发、构建、部署、发布。系统整体上的把控,是在发布、测试过程中所有团队共同参与的结果,这时候开发变成了运维,运维变成了顾问,这就是Devops的思想,因此微服务更适合小型团队的持续化发布;反之SOA是自顶向下的实施模式,必须进行分层式的过程管理,要有人对流程管理负责、ESB企业数据总线负责、各个构件服务也是不同组织的项目或开发团队负责。因此SOA架构在实施过程中具备清晰的责任关系,特别适合项目跨企业、大企业跨部门的复杂应用系统建设。这和微服务的实施过程可以说是天壤之别。

(4)微服务与SOA一样,都是在分布式环境下,形成很多不同的独立服务,相对于SOA,微服务是细粒度的,SOA是粗粒度的,而且它们在技术的异构性的兼容上有着一致的风格,微服务是通过通讯机制,主要是Restful,实现不同微服务的相互协作,但微服务自身用什么技术来实现,那都不影响;同样前面的内容也说清楚了SOA的服务接口定义和Webservices实现,本身就是为了统一兼容异构平台之间的协作。

3)微服务的特点

优点:

易于开发和维护: 一个微服务只会关注一个特定的业务功能,所以它业务清晰、代码量较少。 开发和维护单个微服务相对简单。而整个应用是由若干个微服务构建而成的,所以整个应用也会被维持在一个可控状态。

单个微服务启动较快: 单个微服务代码量较少, 所以启动会比较快。

局部修改容易部署: 单体应用只要有修改,就得重新部署整个应用,微服务解决了这样的问题。 一般来说,对某个微服务进行修改,只需要重新部署这个服务即可。

**技术栈不受限:**在微服务架构中,可以结合项目业务及团队的特点,合理地选择技术栈。例如某些服务可使用关系型数据库MySQL;某些微服务有图形计算的需求,可以使用Neo4j;甚至可根据需要,部分微服务使用Java开发,部分微服务使用Node.js开发。

缺点:

运维要求较高: 更多的服务意味着更多的运维投入。在单体架构中,只需要保证一个应用的正常运行。而在微服务中,需要保证几十甚至几百个服务服务的正常运行与协作,这给运维带来了很大的挑战。

分布式固有的复杂性: 使用微服务构建的是分布式系统。对于一个分布式系统,系统容错、网络延迟、分布式事务等都会带来巨大的挑战。

接口调整成本高: 微服务之间通过接口进行通信。如果修改某一个微服务的API,可能所有使用了该接口的微服务都需要做调整。

重复劳动: 很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会开发这一功能,从而导致代码重复。尽管可以使用共享库来解决这个问题(例如可以将这个功能封装成公共组件,需要该功能的微服务引用该组件),但共享库在多语言环境下就不一定行得通了。

总结

最后,我们对架构做一个总结:

1)架构为系统功能勾画了蓝图(就像业务架构告诉了系统要做什么,实现什么样的功能业务)

2)架构为系统设计指明了方向(应用架构告诉实施者遵循什么样的逻辑结构去做)(怎么做

3)架构为系统实施讲清了方法(架构告诉了开发者用什么方法手段去实实在在地完成系统的建设)


参考内容

基本概念理解

1. 架构到底是指什么? & 容易混淆的概念_陈靖-CSDN博客

信息系统分析与设计_中国大学MOOC(慕课) (icourse163.org)

中间件是什么?如何解释比较通俗易懂? - 知乎 (zhihu.com)

软件技术架构

到底什么是架构?回答你关于软件架构的所有疑惑。_哔哩哔哩_bilibili

架构分类

架构的本质_知识库_博客园 (cnblogs.com)

架构设计-谈谈架构-架构 (uml.org.cn)

什么是架构以及架构的分类_maoyeqiu的专栏-CSDN博客_什么是架构

架构设计实践五部曲(五):技术架构的战略和战术原则-InfoQ

应用架构演进

架构设计-谈谈架构-架构 (uml.org.cn)

三层架构详解 | 菜鸟教程 (runoob.com)

SOA/软件架构设计—面向服务的架构(SOA详细解释)-soa (uml.org.cn)

如何通俗易懂地解释什么是SOA? - 知乎 (zhihu.com)

通俗地理解面向服务的架构(SOA)以及微服务之间的关系 (qq.com)

其他参考内容

浅谈架构、框架、模式、模块、组件、插件、控件、中间件_筱葭的博客-CSDN博客

架构漫谈(一):什么是架构?_知识库_博客园 (cnblogs.com)

每个架构师都应该研究下康威定律_知识库_博客园 (cnblogs.com)

好的架构是进化来的,不是设计来的_知识库_博客园 (cnblogs.com)

架构漫谈(四):如何做好架构之架构切分_知识库_博客园 (cnblogs.com)

什么是应用架构_Lan_____的博客-CSDN博客_应用架构

应用架构之道:分离业务逻辑和技术细节-阿里云开发者社区 (aliyun.com)

架构技术演进_小猴子的博客-CSDN博客_技术架构演变