从0开始学架构-概念和基础

目录

架构概念

概念

重新定义架构

复杂度来源

高性能

高可用

可扩展性

低成本

安全

规模

架构设计原则

合适原则

简单原则

演化原则

架构设计流程


架构概念

概念

系统泛指一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体,它的意思是
“总体”,“整体”或者“联盟”

  1. 关联,系统是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个系统
  2. 规则,系统内的个体需要按照指定的规则运作,而不是单个个体各自为政,规则规定了系统内个体分工和协作的方式
  3. 能力,系统能力与个体能力有本质的差别,系统能力不是个人能力之和,而是产生了新的能力

子系统也是由一群有关联的个体所组成的系统,多半是更大系统中的一部分
以微信为例

  • 微信本身是一个系统,包含聊天,登陆,支付,朋友圈等子系统
  • 朋友圈这个系统又包括动态,评论,点赞等子系统
  • 评论这个系统可能又包含防刷子系统,审核子系统,发布子系统,存储子系统
  • 评论审核子系统不再包含业务意义上的子系统,而是包括各个模块或组件,这些模块或组件本身也是另外一个维度上的系统,如MySql,Redis等存储系统,但不是业务子系统

模块
软件模块(Module)是一套一致且互相有紧密关联的软件组织,它包含程序和数据结构两部分,现代软件开发往往
利用模块作为合成的单位
模块的接口表达了由该模块提供的功能和调用它所需的元素
模块是可能分开被编写的单位,这使得它们可再用,并允许开发人员同时协作,编写及研究不同的模块

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

模块和组件都是系统的组成部分

  • 从逻辑的角度来拆分得到的单元就是“模块”
  • 从物理的角度来拆分得到的单元就是“组件”

如一个学生信息系统

  • 从逻辑角度拆分,包括“登陆注册模块”,“个人信息模块”,“个人成绩模块”
  • 从物理角度拆分,包括Nginx,Web服务器,MySql


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

  • 框架是组件规范,如MVC是一种常见的开发规范
  • 框架提供基础功能的产品,如SrpingMVC

从开发规范角度分解,学生管理系统采用MVC框架,因此架构又变成了MVC架构
这是从不同的视角来拆分的架构,IBM的架构试图著名的4+1 视图

重新定义架构

软件架构指软件系统的顶层结构

  1. 系统由一群关联的个体组成,这些个体可以是子系统,模块,组件等,架构需要明确系统包含哪些个体
  2. 系统中的个体需要根据某种规则运作,架构需要明确个体运作和协作的规则
  3. 顶层结构可以更好的区分系统和子系统,避免将系统架构和子系统架构混淆导致架构层次混乱

架构设计的误区

  • 因为架构很重要,所以要做架构设计
  • 不是每个系统都要做架构设计吗
  • 公司流程要求系统开发过程中必须有架构设计
  • 为了高性能,高可用,可扩展,所以要做架构设计


软件开发历史

  1. 机器语言(1940年之前)
  2. 汇编语言(20世纪40年代)
  3. 高级语言(20世纪50年代)
  4. 第一次软件危机与结构化程序设计(20世纪60年代-20世纪70年代)
  5. 第二次软件危机与面向对象(20世纪80年代)

第一次危机根源在于软件逻辑变得非常复杂
第二次危机根主要体现在软件的扩展变得非常复杂
只有规模较大的软件系统才会面临软件架构相关的问题

  • 系统规模庞大,内部耦合严重,开发效率低
  • 系统耦合严重,牵一发动全身,后续修改和扩展困难
  • 系统逻辑复杂,容易出问题,出问题后很难排查和修复

1964年的IBM360大型系统,《人月神话》

整个软件技术发展的历史,其实就是一部与“复杂度”斗争的历史,架构的出现也不例外
脚骨设计的主要目的是为了解决复杂度带来的问题
 

复杂度来源

高性能

新技术替代旧技术后,复杂度不会提升
新技术开创了新领域后,系统设计面临技术之前判断选择或组合,会带来复杂度提升
软件系统中高性能复杂度
1.单台机器内部为了高性能带来的复杂度
2.多台机器集群为了高性能带来的复杂度

单机复杂度

  1. 最简单的输入-输出
  2. 批处理
  3. 多进程,进程间通讯
  4. 多线程

为了让CPU能够同时执行计算任务,实现真正意义删的多任务并行,其方案有

  • SMP 对称多处理器结构 Synmmetirc Multi-Processor
  • NUMA 非一致存储访问结构 Non-Uniform Memory Access
  • MPP 海量并行处理结构 Massive Parallel Processing

集群复杂度
业务发展如双11和春节红包带来的复杂度
任务分配

  1. 单机变多机后需要增加分配器,可能是硬件网络设备(F5,交换机),可能是软件(LVS),可能是负载均衡(N给你想,HAProxy),也可以是memcached那样的客户端算法分配
  2. 任务分配器和业务服务器之间有链接和交互
  3. 任务分配器需要增加分配算法,如按轮询,权重,负载

使用分配器后实际会打个8折

如业务继续扩大,分配器本身也需要扩展成多台

  1. 需要将不同的用户分配到不同的任务分配器上,方法包括NDS轮询,智能DNS,CDN,GSLB全局负载均衡
  2. 之前的1对多变成了多对多的网状结构
  3. 相应的状态管理,故障处理复杂度也大大增加

存储系统,运算系统,缓存系统都可以按照任务分配的方式来搭建架构

任务分解
将业务拆分为更多的组成部分
如微信后台从逻辑上将各个子业务进行拆分,包括接入,注册登录,消息,LBS,摇一摇,漂流瓶,聊天,视频,
朋友圈等业务
通过拆分业务也可以提升性能

  1. 简单的系统更容易做到高性能
  2. 可以针对单个任务进行扩展
  3. 不能无限制拆分,分的太细各子系统之间调用增多性能反而下降


高可用

是指系统无中断的执行器功能的能力,代表系统的可用程序,是进行系统设计时的准则之一
软件会有bug,硬件会有故障,还有各种不可避免的外部因素
系统的高可用方案五花八门,本质上都是通过冗余来实现高可用的

计算高可用

  1. 增加一个任务分配器,和高性能类似,此时会增加成本,维护,可用性等方面问题
  2. 任务分配器跟业务服务器之间有连接和交互
  3. 任务分配器需要增加分配算法,如主备(冷备,温备,热备),主主
  4. ZooKeeper是1主多备,Memcached是全主0备

存储高可用
整个系统高可用设计的关键点和难点就在于存储高可用
正常的传输延迟,异常的传输中断,都会导致系统在某个时间点或时间段数据不一致,这致会导致业务问题
如果完全不做冗余,系统的整体高可用又无法保证
存储高可用的难点不在于如何备份数据,而在于如何减少或规避数据不一致对业务造成的影响
存储高可用的CAP,无法同时满足 一致性,额可用性,分区容错性


高可用状态决策
计算高可用,存储高可用,其基础都是状态决策,即系统需要能够判断当前的状态是正常还是异常

  • 独裁式,不会出现决策混乱的问题,但决策者本身故障时系统无法实现准确的状态决策
  • 协商式,主备模式,因网络连接故障可能会出现两主,或两备的情况增加协商主机之间的连接,如2个/3个连接可降低中断带来的影响,但连接之间若信息也不一致会有问题
  • 民主式,多个独立的个体通过投票的方式来进行状态决策如ZooKeeper

  可能会出现脑裂问题,解决办法是投票节点数必须>系统总结点书一半,但会降低可用性

如何选择合适的高可用方案,是一个复杂的分析,判断,取舍的过程


 

可扩展性

指系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或仅需要少量修改就可
以支持,无须整个系统重构或重建
面向对象和设计模式(可服用面向对象软件的基础)就是为了解决可以扩展性带来的问题

1.预测变化,软件系统和硬件,其复杂性在于
   不能每个设计点都考虑可扩展性
   不能完全不考虑可扩展性
   所有的越策都存在出错的可能
   没有明确的标准,更多是靠经验和直觉
2.应对变化
   

将变化封装在一个变化曾,将不变的部分封装在一个独立的稳定层
系统需要拆分出变化层和稳定层
需要设计变化曾和稳定层之间的接口

提炼出一个抽象层,一个实现层,当加入新的功能时,只乤增加新的实现无须修改抽象层
如装饰模式

低成本

如A方案需要1W台机器,B方案需要8K台机器

  • 高性能和高可用是通过增加更多服务器来实现的
  • 低成本需要减少服务器才能达到低成本的目的,因此低成本和高性能,高可用是冲突的
  • 低成本很多时不是架构设计的首要目标,而是架构设计的附加约束
  • 我们首先定一个成本目标,如果方案达不到只能换或者调整成本目标

低成本给架构设计带来的复杂度体现在需要“创新”‘才能得到目标,如

  • NoSql,解决关系型数据库无法应对高并发访问带来的压力
  • 全文搜索引擎,解决了关系型数据库like搜索的低效率问题
  • Hadoop,解决了传统文件系统无法应对海量数据存储和计算的问题
  • FaceBook,HipHop PHP将其翻译为C++执行,后来改为HHVM类似JVM
  • Linkedin,开发的Kafka

安全

从技术角度看,分为两类
功能安全,XSS,SQL注入,更多是编码方面和架构无关,通过框架来不断保证,但框架也会有问题
架构安全,防火墙成本高,但DDOS会造成流量拥塞防火墙也没辙,只能靠运营商的贷款和流量清洗能力


规模

很多企业系统没有高可用,也无扩展性,但系统还是非常复杂逻辑多
1.功能越来越多,导致系统复杂度指数上升
  3个功能的复杂度=6,,8个功能的复杂度=36
2.数据越来越多,系统复杂度发生质变
  如MySq单表不能超过5000W行,分库分表后会带来复杂度


 

架构设计原则

架构和开发不同,架构有不确定性
软件开发领域有一整套完整的规范,但是架构设计并没有,更多是靠经验和直觉
有几个架构设计的同性原则
合适原则,简单原则,演化原则


合适原则

合适优于业界领先
某亿级用户平台失败案列
1.
没有那么多人,却想干那么多活
2.没有那么多积累,却想一步登天
3.没有那么卓越的业务场景,却幻想灵光一闪成为天才
优秀的架构是在企业当前人力,条件,业务等各种约束下设计出来的,能够合理的将资源整合在一起并发挥最大
功效,并能快速落地


简单原则

简单优于复杂
复杂在制造领域代表先进,在建筑领域代表领先,但在软件领域代表的是问题

结构的复杂性
1.组件越多,就越有可能其中某个组件出现故障
2.某个组件改动,会影响关联的所有组件,这些被影响的组件同样会继续递归影响更多的组件
3.定位一个复杂系统的问题总是比简单系统更加困难

逻辑的复杂性
逻辑复杂会导致软件工程的每个环节都有问题
复杂的电路设计好后就不会再变
软件系统投入使用后,会不断修改系统,复杂性在整个系统生命周期中一直都有很大影响
《UNIX编程艺术》的KISS keep it simple stupid


演化原则

演化优于一步到位
从和目的,主题,材料和结构的联系上来说,软件架构可以喝建筑物的架构相比拟
对于建筑来说,永恒是主题,对于软件来说变化才是主题
软件架构设计更加类似于大自然设计一个生物
1.设计出来的架构要满足当时的业务需求
2.架构要不断的再实际应用过程中迭代,保留优秀的设计,修复有缺陷的设计,改正错误的设计,不断完善
3.当业务发生变化时,架构要扩展,重构,甚至重写,代码也许会重写,但又价值的经验教训逻辑设计等却可以在新架构中延续

架构设计流程

识别复杂度
将主要的复杂度问题列出来,然后根据业务,技术,团队等综合情况进行排序,优先解决当前面临的最主要的复
杂度问题

设计备选方案
架构师需要对已存在的技术非常熟悉,对已验证过的架构模式熟悉,再根据对业务的理解,选择合适的架构模式
进行组合,再对组合后的方案进行修改和调整
《技术的本质》一书中对技术的组合有清晰的阐述
新技术都在现有技术的基础上发展起来的,现有技术又源于先前的技术,将技术进行功能性分组,可以大大简化
设计过程,这是技术“模块化”的首要原因
技术的“组合”和“递归”特征,将彻底改变我们对技术本质的认识

备选方案要3-5个
备选方案的差异要比较明显
备选方案的技术不用只限于已经熟悉的技术

评估和选择备选方案
360读环评
常见的发难质量属性点有:性能,可用性,硬件成本,项目投入,复杂度,安全性,可扩展性
如果某个质量属性和业务发展有关,需要评估未来业务发展规模时,可以将当前业务规模乘以2-4即可
按优先级选择,综合当前的业务发展情况,团队人员规模和技能业务发展预测等,将质量属性按照优先级排序,
优先挑选满足第一优先级的
 

猜你喜欢

转载自blog.csdn.net/hixiaoxiaoniao/article/details/86714280