概叙
算法 = 逻辑 + 控制
程序 = 数据结构 + 算法
软件 = 数据结构 + 算法 + 文档
硬件 = CPU + 内存 + 磁盘 +网络设备 + 输入/输出设备
服务器 = 硬件 + 操作系统
系统/计算机系统 = 服务器 + 应用软件 + 用户
系统架构/软件架构 = 系统草图/蓝图/抽象(系统结构、系统行为)
数据结构的两大用途:
- 存放要处理的数据。
- 实现算法策略,如迷宫地图中探索方向的增量数。
软件架构分类
按照当前我国的各种不同的关注角度,能够将软件架构划分成为三种类型。
1、逻辑架构
软件系统系统当中的各个元件之间所存在的关系,比如外部系统接口、用户界面、商业逻辑元件、数据库等。
2、物理架构
究竟是怎样做到在硬件当中放置软件元件。例如处于上海与北京进行分布的分布式系统的物理架构,这也就是说全部的元件都是属于物理设备,主要的有主机、整合服务器、应用服务器、代理服务器、存储服务器、报表服务器、Web服务器、网络分流器等。最直接的就是系统的网络拓扑图。
3、系统架构
系统架构一般涉及到两个方面的内容,其一是业务架构,其二是软件架构。业务架构描述了业务领域主要的业务模块及其组织结构。软件架构是一种思想,一个系统蓝图,是对软件结构组成的规划和职责设定。一个软件里有处理数据存储的处理业务逻辑的、处理页面交互的、处理安全的等许多可逻辑划分出来的部分。
软件机构作用
1、开发新产品过程中软件架构所具备的作用分析
所谓的软件架构则是属于在现实的世界与计算机领域所搭建起来的一座沟通的桥梁,具体来说,其作用主要为以下几点。
第一点就是进行业务目标的上乘。从本质上来看,软件架构往往存在着出于将业务目标完成而必须开展相应的大局规划的责任;
第二点所指的就是进行技术决策的下接。凭借着把面向业务的相关需求往面向技术方向转向的软件架构设计方案,这可以将行之有效的限制与指导提供给后续的技术开发工作;
第三点就是有效的将新产品的质量提升;
第四点所指的就是进相应的新产品开发过程的组织;
第五点所指的就是借助于相应的迭代实施相应新产品开展与增量的交付;
第六点则是说控制所具备的复杂性,立足于相应的分而治之的思想,从而能够对问题的复杂性实施相应的控制。
2、开发软件产品过程中系统架构所具备的作用分析
第一就是将所具备的相应的核心知识予以固化;
第二就是可以提供相应的可重用资产;
第三就是将产品推出的周期进行有效的缩短;
第四就是使得产品开发与维护的总成本得以最大限度的降低;
第五就是将产品的质量有效的提升;
第六就是为批量控制提供有效的支持。
3、软件产品线架构所具备的特点分析
软件产品线架构就是说根据一个公司或者是某一个组织内部那些一系列的产品所进行设计的相应的通用架构。那么就能够了解到这样的一系列产品存在着特别多的相似之处那么这些能够借助同一个架构或者部分共享来实施具体实现,使得生产率得到最大限度的提升。软件产品线架构主要存在着以下的作用:
第一个作用就是应该将一系列的明确许可的变化进行考虑;
第二个作用所指的就是必须做到文档化;
第三个作用就是说应该可以存在着相应的产品创建者指南,将实例化架构的整个过程进行描述。
4、维护软件过程中软件架构的作用分析
从本质上来看,相应的软件维护工作主要的来源是Bug与需求变更。往往修复一个Bug与增加一个新的功能,那么通常都会涉及到架构环节的一条模块协作链,针对这样的情况,软件架构比有利于维护工作的开展;反之,如果对于架构并不能了解,相应的进行程序的盲目修改,这也就会存在着可能性对架构设计的思路造成未必,从而导致整个系统所存在的架构逐步显得比较混乱,这也就会存在着可能性导致出现不可思议的Bug与问题。
5、软件升级过程中软件架构的作用分析
相应的软件架构则是通过对软件系统实施持续性的修改,还应该必须做好重构,往往对其实施重构主要是两种状况:
第一种状况就是特别混乱的架构,从而导致实施一个比较小的改动就会出现牵动全身;
第二种状况所指的就是即将实施的升级软件存在着比较大的力度,之前的软件架构与新的需求根本就不能适应。
相应的软件架构予以重构则是属于再工程的一种情况,往往必须实施的步骤为逆向工程、重新规划、正向工程这样的三个步骤。
1.软件架构体系
1.1. 系统与子系统
系统:泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。
- 关联:系统是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个系统。例如,把一个汽车发动机和一堆苹果放在一起不能称之为一个系统,把发动机、底盘、轮胎、车架组合起来才能成为一台汽车,构成一个系统。
- 规则:系统内的个体需要按照指定的规则运作,而不是单个个体各自为政。规则规定了系统内个体分工和协作的方式。例如,汽车发动机负责产生动力,然后通过变速器和传动轴,将动力输出到车轮上,从而驱动汽车前进。
- 能力:系统能力与个体能力有本质的差别,系统能力不是个体能力之和,而是产生了新的能力。例如,汽车能够载重前进,而发动机、变速器、传动轴、车轮本身都不具备这样的能力。
子系统:子系统也是由一群有关联的个体所组成的系统,多半会是更大系统中的一部分。子系统的定义和系统定义是一样的,只是观察的角度有差异,一个系统可能是另外一个更大系统的子系统。
以微信为例来做一个分析:
- 微信本身是一个系统,包含聊天、登录、支付、朋友圈等子系统。
- 朋友圈这个系统又包括动态、评论、点赞等子系统。
- 评论这个系统可能又包括防刷子系统、审核子系统、发布子系统、存储子系统。
- 评论审核子系统不再包含业务意义上的子系统,而是包括各个模块或者组件,这些模块或者组件本身也是另外一个维度上的系统。例如,MySQL、Redis 等是存储系统,但不是业务子系统。
1.2. 模块、组件、服务
- 模块:是一套一致而互相有紧密关连的软件组织。它分别包含了程序和数据结构两部分。现代软件开发往往使用模块作为合成的单位
- 组件:自包含的、可编程的、可重用的、与语言无关的软件单元,组件可以很容易被用于组装应用程序中
模块和组件都是系统的组成部分,只是从不同的角度拆分系统而已。例如:
- 从逻辑的角度来拆分系统后,得到的单元就是“模块” ;从物理的角度来拆分系统后,得到的单元就是“组件” 。
- 划分模块的主要目的是职责分离;划分组件的主要目的是单元复用。
例如我们要做一个学生信息管理系统,这个系统从逻辑的角度来拆分,可以分为:登录注册模块、个人信息模块、个人成绩模块;从物理的角度来拆分,可以拆分为应用程序、 Nginx、Web 服务器、MySQL等
- 服务: 服务和组件有某种相似之处:它们都将被外部的应用程序使用。两者之间最大的差异在于:组件是在本地使用的(例如Jar文件);而服务是运行起来的,要通过同步或异步的远程接口来远程使用(例如RESTFul接口、web service、消息系统、RPC,或者socket)
服务是可以单独运行,并且对外提供功能的一种形式。可以将一个复杂的项目分解成多个服务。当某一个服务挂掉时不会拖垮整个系统。如果没有服务化,每当一个新的功能被添加到系统中就会影响到所有功能;如果采取服务化,每个服务只对其上下游的服务负责。
1.3. 软件架构体系
2、架构原则
2.1. 解耦
在软件工程中,耦合指的就是对象之间的依赖性。对象之间的耦合度越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则就是高内聚低耦合。
耦合性存在于各个领域,而非软件设计中独有的,理论上说绝对的零耦合是做不到的,但可以通过一些方法将耦合降至最低,降低耦合度即可理解为解耦,在设计上解耦的核心思想是【彼此独立,互不依赖】。
2.2. 分层
分层结构是最为流行、应用最广泛的应用软件的设计方式。在应用了分层结构的系统中,各个子系统按照层次的形式组织起来,上层使用下层的各种服务,而下层对上层一无所知。每一层都对自己的上层隐藏其下层的细节。
经典三层架构:
在软件架构中,经典三层架构自顶向下由用户界面层、业务逻辑层、数据访问层组成。在提出该分层架构的时代,多数系统往往较为简单,本质上都是一个单体架构的数据库管理系统。这种分层架构有效地隔离了业务逻辑与数据访问逻辑,使得这两个不同关注点能够相对自由和独立地演化。经典的三层架构如下所示:
分层的设计原则是:保证同一层的组件处于同一个抽象层次。即所谓的“单一抽象层次原则”。这一原则可以运用到分层架构中。比如下图所示:
2.3. 封装
假设我们有一个程序,它在逻辑上有一些不同的对象,并且这些对象彼此之间会相互交流。
在一个类中,当每个对象的状态保持相对孤立,就实现了封装。其余的对象并不能观察到这个对象的状态。他们能做到的只有调用一些被称作“方法”的通用功能。
因此,对象使用方法掌控着自己的状态,除非明确允许,没有其他人可以接触到它。如果你想和某个对象交流,你需要使用提供的方法。但在默认情况下,你无法改变对象的状态。
3、架构的方法
架构图是为了表示软件系统的整体轮廓和各个组件之间的相互关系和约束边界,以及软件系统的物理部署和软件系统的演进方向的整体视图。要让干系人理解、遵循架构决策,就需要把架构信息传递出去,架构图就是一个很好的载体。不同的视角和角色,关注点也是不同的,看到的架构图是不一样的。
3.1、业务架构
使用者:CEO、CIO、CTO、产品总监
核心业务流程:
核心能力:
3.2、功能架构
使用者:产品总监、产品经理
示例: 黑马头条功能架构图
3.3、系统架构
使用者:系统架构师
3.4、 技术架构
使用者:系统架构师
示例二:冷链项目技术架构图
3.5、数据架构
使用者:CTO、系统架构师、数据架构师
示例一:数据模型
示例二:大数据平台架构
3.6、部署架构
使用者:运维架构师
示例二:冷链项目部署架构图
4、架构演进之路
4.1、单体架构
公司发展的初期,资金少、用户少,需要的软件产品的数据和并发量都比较小,这个时期大多数的软件系统只需要单一服务器就可以满足需求,所有的业务逻辑都在单一应用系统,单应用、单数据库。数据库部署在和应用相同的虚拟机或服务器上,或者放置在另外一台机器上。此时的架构图如下:
或
- 操作系统:windows、linux
- 应用服务器:tomcat、jetty、jboos、apache、weblogic、websphere...
- 数据库:mysql、oracle、db2...
- 应用系统:可以用java、php、asp等各种语言开发
这种架构模式优点很明显:
- 节省服务器资源,投入少
- 管理简单:上线、部署、监控、问题排查等都比较简单
- 开发简单:软件系统功能整合在一起,不需要考虑太多服务依赖等问题,代码管理也比较简单明了。
- 测试简单
随着公司和业务进入快速发展时期,软件系统面临来自多方面的考验:
单体架构的缺点也越发的凸显出来:
- 可用性差:应用和数据库都是单点,无论应用还是数据库出现问题,整个系统的就会不可用了
- 稳定性差:系统耦合度高,新增或者修改任何一个功能,哪怕只是一行代码,也需要重启服务器,此时系统是不可用的
- 性能差:单一的应用服务器和数据库服务器,性能总会有上限的,当用户变多或者准确的说相同时刻并发访问多时,系统就容易挂掉了
4.2、分布式架构
单体架构有着明显的缺陷,随着系统访问量的增多,这些缺陷越来越凸显,为了解决这些缺陷,架构升级了,变成了分布式架构。分布式,就是多个实例提供服务。下面我们来简单介绍下常见的一些解决方案。
1、应用集群
- 反向代理服务器:把用户请求反向路由到应用服务器,常见的反向代理服务器是Nginx或HAProxy
- 应用服务器:集群化部署
- 数据库服务器:主从部署
架构优点:
- 可用性高:代理服务器、应用服务器、数据库服务器都是做了集群,当某台机器挂掉后,其他机器能够几乎无感的接替下任务
- 性能比单体架构高:用户的请求分发到多个应用服务器上,整体性能接近单体结构的三倍
- 安全性高:外网用户访问的是反向代理服务器,应用和数据库隔离在内网中
2、分布式缓存
缓存分为多级缓存,比如本地缓存(JVM中),分布式缓存服务器(Redis集群等)。本地缓存的访问速度更快一些,但是受应用服务器内存限制,其缓存数据量有限,而且会出现和应用程序争用内存的情况。远程分布式缓存可以使用集群的方式,部署大内存的服务器作为专门的缓存服务器,可以在理论上做到不受内存容量限制的缓存服务。常见缓存服务器包括Redis、Memcached等。使用缓存后,数据访问压力得到有效缓解。
3、业务拆分
业务进一步发展,用户越来越多,系统又出现了瓶颈,此时整个电商系统可以做系统拆分了,系统拆分分为水平拆分和垂直拆分。
水平拆分:
拆分成商品、订单、交易、用户、支付等多个系统,每个系统都都是多台服务器构成的集群。
垂直拆分:
将一些公共业务和服务,如用户中心拆分成注册登录中心和用户中心,短信、文件、消息等各种公共服务,从业务系统中拆分剥离出来。
这种架构的优势也比较明显,一方面,应用系统增加了,能够响应用户的请求也会变多,另一方面公共服务能够提供给所有的应用使用,达到服务复用的效果。但是大家需要注意的是数据库有可能只是一个,而单一数据库服务器的处理能力必然是有限的,随着用户并发量的持续增多,数据库将会是系统的瓶颈。
4、分库分表和读写分离
读写分离:
在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈。目前大部分的主流数据库都提供主从热备功能,通过配置数据库的主从关系,可以将一台数据库服务器的数据更新同步到另外的数据库服务器上。网站利用数据库的这一功能,实现数据库读写分离,从而改善数据库负载压力。
应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据更新同步到从数据库,这样当应用服务器读数据的时候,就可以通过从数据库获得数据。
分库分表:
随着数据库中的数据量越来越大,相应的,查询所需要的时间也越来越多,这个时候,相当于数据的处理遇到了瓶颈,另一方面单库发生意外的时候,需要修复的是所有的数据,而多库中的一个库发生意外的时候,只需要修复一个库。基于此,分库分表就成了必然。分库分表的策略很多,如按照用户、订单、交易、商品等进行分库,不同的数据库中按照时间进行分表。
分库分表带来性能上的显著提升,但相应的管理和维护成本也比较高,比如数据库服务器的维护、分表策略的维护。为了便于应用程序访问分库分表、读写分离后的数据库,通常在应用服务器端使用专门的数据访问模块,使数据库的分库分表和读写分离对应用透明。
5、静态化和CDN
随着网站业务不断发展,用户规模越来越大,和中国复杂的网络环境,不同地区的用户访问网站时,速度差别也极大。为了提供更好的用户体验,留住用户,网站需要加速网站访问速度。主要手段有使用页面的静态化和CDN。
操作方式上把一些页面,比如某些商品的详情信息,在发布商品时将页面静态化,静态化页面和静态资源可以放在CDN服务器,部署在网络服务提供商的机房,用户在访问静态资源时,可以很好的利用CDN的优点,从距离自己最近的网络提供商机房获取数据。
6、异步解耦
应用之间的服务存在互相调用的情况,但有些场景下,并不需要同步调用,比如某个业务完成后,需要短信通知对方,而短信接收的时间晚几秒钟都是可以接受的,此时就不需要同步处理了,我们可以使用消息队列,把发送短信的内容扔到消息队列中,达到异步处理的效果,从而增强业务系统的性能,此时对于服务之间也达到了解耦的功能,服务之间的依赖减少了。
4.3、微服务架构
微服务架构是分布式架构的深化,分布式架构偏向于部署和环境,比如上边提到的应用、数据库、缓存等,在多台机器上进行部署,就属于分布式。微服务架构通过业务拆分实现服务组件化,通过组件组合快速开发系统,业务单一的服务组件又可以独立部署,使得整个系统变得清晰灵活。
大量的分布式服务又使得架构实现面临问题,如服务注册发现,服务统一接入和权限控制,服务的负载均衡,服务配置的集中管理,服务熔断,服务监控等。
所以微服务架构是由这些基础的服务组件和业务微服务组件共同组成:
- 服务注册发现组件:进行服务治理
- 服务网关组件:提供统一入口和权限控制
- 负载均衡组件:提供客户端或服务器端的负载均衡
- 集中配置组件:提供服务集中管理
- 熔断器组件:提供服务熔断
- 服务追踪组件:提供服务监控
采用微服务架构后,项目可以快速迭代与持续交付。但是也带了一些弊端,开发人员除了需要关注业务逻辑实现外还需要考虑业务的一系列问题,比如服务注册,服务发现,服务通讯,负载均衡,服务熔断,服务超时等,这些是非常重要的。大多数时候,我们需要依赖第三方库或者组件来提供这些服务,例如Hystrix,Eureka、Zookeeper等组件,在其服务组织中起到了广泛的应用。
5、 服务化(大中台+小前台)
5.1、为什么需要服务化
传统企业或者很多企业的软件,大多不止一套系统,都是各个独立大系统的堆砌。整体存在的问题是:
- 扩展性差
- 可靠性不高
- 维护成本还很大
- 重复轮子很多
非常容易能够想到,解决这些问题的方法是:组件化、服务化。
微服务架构,将各个组件或者模块分散到各个服务中,对整个系统实现解耦。那微服务架构强调的重中之重就是业务系统需要完善的组件化和服务化。什么是组件化?
组件化,即将一个大系统,按照一定的业务或者技术维度,拆分成独立的组件。目的是为了分而治之,为了可重用,为了减少耦合度。比如按照技术维度:文件上传下载组件、短信发送组件、搜索组件、缓存组件;按照业务维度:用户中心、商品中心、支付中心等。
阿里巴巴提出 大中台,小前台战略,就是把组件化、插件化、服务化解决方案到极致。通过产品线公共业务或者技术下沉,形成各种技术中台或者业务中台。
5.2、服务化的好处
- 调用简单
- 代码复用
- 业务隔离
- 数据库解耦
5.3、服务化的问题
有利必有弊,服务化也会面临很多问题:
- 本身不大的系统,业务不复杂的系统也不需要微服务架构
- 多个模块数据库,分布式事务是一个挑战
- 增加了测试、运维等事务的复杂性