架构基础学习
从0开始学架构 0. 开篇 架构设计的相关特性:
架构设计思维和程序设计思维差异较大。架构设计的关键思维是判断和取舍,程序设计的关键思维是逻辑和底层实现。 缺少体系化的培训和训练机制 程序员对架构设计理解存在很多误区 内容:
架构基础 高性能架构模式 高可用架构模式 可扩展架构模式 目标:
清楚地理解架构设计相关的概念、本质、目的,避免架构师在实践过程中把握不住重点、分不清主次,眉毛胡子一把抓,导致架构设计变形或者“四不像” 。 掌握通用的架构设计原则,无论是何种业务或技术,架构师在判断和选择的时候有一套方法论可以参考,避免架构设计举棋不定,或者拍脑袋式设计。 掌握标准的架构设计流程,即使是刚开始做架构设计的新手,也能够按照步骤一步一步设计出合适的架构,避免某些步骤缺失导致错误的架构设计。 深入理解已有的架构模式,做到能够根据架构特点快速挑选合适的模式完成架构设计,或者在已有的模式上进行创新,或者将已有的模式组合出新的架构。 掌握架构演进和开源系统使用的一些技巧。 1. 架构到底是什么 1.1 三组概念 三组概念:
系统与子系统。具有关联的个体按照一定规则组织起来完成个体所不能完成的工作,成为系统。子系统是更大系统中的一部分。 模块(Module)与组件(component)。从业务逻辑拆分,得到的有程序和数据结构组成的软件组织成为模块。模块的接口表达了其功能。从屋里部署的角度拆分,得到的就是组件。划分模块的主要目的是职责分离,划分组件的目的是单元服用。模块与组件都是系统的组成部分,只是拆分角度不同。 框架(Framework)与架构(Architecture)。框架是组件规范,提供基础功能的产品。架构是指软件系统的基础结构,创造这些基础结构的准则和描述。也就是说框架关注的是规范,架构关注的是结构。 一个系统的架构只包含顶层这一层的架构,不包含下属子系统的架构。一个系统的架构从业务逻辑、物理部署不同角度看,有着不同的结构。
1.2 4R架构 软件架构指软件系统的顶层(Rank)结构,它定义了系统由哪些角色(Rule)组成,角色之间的关系(Relation)和运作规则(Rule)。通常Rank,Relation,Rule可以通过系统架构图展示,Rule可以通过系统序列图展示。 1.3 架构设计的历史背景 随着软件系统规模的增加,计算相关的算法和数据结构不再构成主要的设计问题;当系统由许多部分组成时,整个系统的组织,也就是所说的"软件架构",导致了一系列新的设计问题。
1.4 架构设计的目的 架构设计的主要目的是为了解决软件系统复杂度带来的问题 设计一个系统时需要考虑: 性能、可扩展性、高可用、安全性、成本。
2. 复杂度来源 2.1 高性能 软件系统中高性能带来的复杂度主要体现在两方面,一方面是单台计算机内部为了高性能带来的复杂度;另一方面是多台计算机集群为了高性能带来的复杂度。
单机复杂度 操作系统为软件系统提供了运行环境,前者的复杂度也决定了后者的复杂度。操作系统由最初的手工操作,到批处理系统,然后进程的提出+分时复用,使用任务看起来像是并行执行,然后发展到多线程。最后发展到多核CPU。单机的复杂度来源于多进程、多线程、多核共享、通信、互斥等。
集群复杂度 通过增加机器来提升系统的性能。常见的方法:
任务分配 每台机器都可以处理完整的业务。随着业务越来越复杂,分配器集群和业务集群变得更加庞大。主要面临:如何将用户请求分配到分配集群的节点上,连接建立、检测、中断后处理。分配节点到业务节点如何分配。机器集群的状态管理、故障处理等问题。
任务分解 任务分配的方式中,每个业务节点拥有完整的业务逻辑。但是若是业务逻辑过于复杂,单机的性能会越来月拆,通过任务分配的方式收益将越来越小。此时可以将完整的业务拆分成若干独立的相对简单的子业务。 任务分解方式的理由: 简单的子系统更容易做到高性能 可以针对单子子系统进行扩展 但是并非任务分解越细越好,子系统之间的协作是有损的。 2.2 高可用 高可用:系统无中断地执行其功能的能力。 高可用实现方案本质都是通过"冗余"来实现的。高性能增加机器的目的在于扩展处理性能;高可用增加机器的目的在于冗余处理单元。
计算高可用。 存储高可用。存储高可用的难点不在于如何备份数据,而在于如何减少或者规避数据不一致对业务造成的影响。CAP定理表明,系统不可能同时满足一致性、可用性、容错性,最多满足其中的两个。 高可用状态决策。不论是计算高可用还是存储高可用,基础都是“状态决策”,即系统需要能够判断当前的状态是正常还是异常,并在异常时采取行动保证高可用。但是通过冗余来实现的高可用系统,状态决策本质上就不可能做到完全正确。 独裁式。只存在单个决策者,不会出现决策混乱的情况,但是决策者自身出现问题时系统不可用。 协商式。两个独立个体通过交流信息,根据规则进行决策。为防止两者信息交流出现异常,通常增加更多的连接。但是多个连接的选择也是个复杂的问题。 民主式。多个独立个体通过投票的方式进行状态决策,按照多数取胜的规则来确定最终的状态。为了应对“脑裂”问题(因为连接问题,集群被分割为两个集群,两个集群各自投票,超出大于1个决策者),民主式决策一般采用“投票节点数必须超过系统节点数的一半”的规则。但是这种策略在节点真正故障时,若可用节点少于一半则陷入不可决策的状态。 2.3 可扩展性 可扩展性指,系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或者需要少量的修改就可以支持,无须整个系统重构或者重建。系统架构设计具体良好可扩展性,应当具体两个基本条件:正确预测变化、完美应对变化。
预测变化 复杂度在于:不能每个设计点都考虑可扩展性;不能完全不考虑可扩展性;所有预测都存在出错的可能性。 2年法则:只预测2年内的可能变化,不要试图预测5年甚至10年的后的变化。 应对变化 提炼稳定层和变化层。核心是通过变化层来隔离变化。一是变化层和稳定层如何拆分,二是两层之间的接口如何设计 提炼抽象层和实现层。核心是通过实现层来隔离变化。 原则:事不过三,三则重构。1写2抄3重构。