关于架构设计:架构设计之一基础架构

2次阅读

共计 4859 个字符,预计需要花费 13 分钟才能阅读完成。

导读:《架构设计》系列为极客工夫李运华老师《从 0 开始学架构》课程笔记。本文为第一局部,次要介绍架构设计的历史背景、相干概念、目标、复杂度、准则以及流程。从整体上对架构设计有所理解。

架构设计的历史背景

机器语言(1940 年之前)

机器语言的次要问题是三难:太难写、太难读、太难改!

汇编语言(20 世纪 40 年代)

实质上还是面向机器的,因为写汇编语言须要咱们准确理解计算机底层的常识。

高级语言(20 世纪 50 年代)

第一次软件危机与结构化程序设计(20 世纪 60 年代~20 世纪 70 年代)

  • 典型体现有软件品质低下、我的项目无奈如期完成、我的项目重大超支等,因为软件而导致的重大事故时有发生。
  • 软件工程同样无奈铲除软件危机,只能在肯定水平上缓解软件危机。
  • 结构化程序设计的次要特点是摈弃 goto 语句,采取“自顶向下、逐渐细化、模块化”的指导思想。结构化程序设计实质上还是一种面向过程的设计思维,但通过“自顶向下、逐渐细化、模块化”的办法,将软件的复杂度管制在肯定范畴内,从而从整体上升高了软件开发的复杂度。

第二次软件危机与面向对象(20 世纪 80 年代)

  • 第二次软件危机的根本原因还是在于软件生产力远远跟不上硬件和业务的倒退。第一次软件危机的本源在于软件的“逻辑”变得非常复杂,而第二次软件危机次要体现在软件的“扩大”变得非常复杂。
  • 结构化程序设计尽管可能解决(兴许用“缓解”更适合)软件逻辑的复杂性,然而对于业务变动带来的软件扩大却无能为力,软件畛域迫切希望找到新的银弹来解决软件危机,在这种背景下,面向对象的思维开始流行起来。

软件架构的历史背景

随着软件系统规模的减少,计算相干的算法和数据结构不再形成次要的设计问题;当零碎由许多局部组成时,整个零碎的组织,也就是所说的“软件架构”,导致了一系列新的设计问题。

  • 零碎规模宏大,外部耦合重大,开发效率低;
  • 零碎耦合重大,牵一动员全身,后续批改和扩大艰难;
  • 零碎逻辑简单,容易出问题,出问题后很难排查和修复

三组容易混同的概念

零碎与子系统

零碎

  • 零碎泛指由一群有关联的个体组成,依据某种规定运作,能实现个别元件不能独自实现的工作的群体。它的意思是“总体”“整体”或“联盟”
  • 关系:零碎是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个零碎。
  • 规定:零碎内的个体须要依照指定的规定运作,而不是单个个体各自为政。规定规定了零碎内个体分工和合作的形式。
  • 能力:零碎能力与个体能力有实质的差异,零碎能力不是个体能力之和,而是产生了新的能力。

子系统

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

总结

一个零碎的架构,只包含顶层这一个层级的架构,而不包含上司子系统层级的架构。所以微信架构,就是指微信零碎这个层级的架构。当然,微信的子系统,比方领取零碎,也有它本人的架构,同样只包含顶层。

模块与组件

模块

软件模块(Module)是一套统一而相互有严密关联的软件组织。它别离蕴含了程序和数据结构两局部。古代软件开发往往利用模块作为合成的单位。模块的接口表白了由该模块提供的性能和调用它时所需的元素。模块是可能离开被编写的单位。这使它们可再用和容许人员同时合作、编写及钻研不同的模块。

组件

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

总结

  • 模块和组件都是零碎的组成部分,只是从不同的角度拆分零碎而已。
  • 从业务逻辑的角度来拆分零碎后,失去的单元就是“模块”;从物理部署的角度来拆分零碎后,失去的单元就是“组件”。划分模块的次要目标是职责拆散;划分组件的次要目标是单元复用。
  • 假如咱们要做一个学生信息管理系统,这个零碎从逻辑的角度来拆分,能够分为“登录注册模块”“个人信息模块”和“集体问题模块”;从物理的角度来拆分,能够拆分为 Nginx、Web 服务器和 MySQL。
  • 业务零碎的架构师,首先须要思考怎么从业务逻辑的角度把零碎拆分成一个个模块角色,其次须要思考怎么从物理部署的角度把零碎拆分成组件角色,例如抉择 MySQL 作为存储系统。然而对于 MySQL 外部的体系架构(是能够不必关注的,也不须要在你的业务零碎架构中展示这些内容。

框架与架构

框架

软件框架(Software framework)通常指的是为了实现某个业界规范或实现特定根本工作的软件组件标准,也指为了实现某个软件组件标准时,提供标准所要求之根底性能的软件产品。

架构

软件架构指软件系统的“根底构造”,发明这些根底构造的准则,以及对这些构造的形容。

总结

  • 框架关注的是“标准”,架构关注的是“构造”。
  • 框架是一整套开发标准,架构是某一套开发标准下的具体落地计划,包含各个模块之间的组合关系以及它们协同起来实现性能的运作规定。

从新定义架构:4R 架构

  • 软件架构指软件系统的顶层(Rank)构造,它定义了零碎由哪些角色(Role)组成,角色之间的关系(Relation)和运作规定(Rule)
  • Rank:它是指软件架构是分层的,对应“零碎”和“子系统”的分层关系。通常状况下,咱们只须要关注某一层的架构,最多展现相邻两层的架构,而不须要把每一层的架构全副糅杂在一起。无论是架构设计还是画架构图,都应该采取“自顶向下,逐渐细化”的形式。
  • Role:它是指软件系统蕴含哪些角色,每个角色都会负责零碎的一部分性能。架构设计最重要的工作之一就是将零碎拆分为多个角色。最常见的微服务拆分其实就是将整体简单的业务零碎依照业务畛域的形式,拆分为多个微服务,每个微服务就是零碎的一个角色。
  • Relation:它是指软件系统的角色之间的关系,对应到架构图中其实就是连接线,角色之间的关系不能乱连,任何关系最初都须要代码来实现,包含连贯形式(HTTP、TCP、UDP 和串口等)、数据协定(JSON、XML 和二进制等)以及具体的接口等。
  • Rule:它是指软件系统角色之间如何合作来实现零碎性能。

架构设计的目标

架构也是为了应答软件系统复杂度而提出的一个解决方案,即架构设计的次要目标是为了解决软件系统复杂度带来的问题。

  • 遵循这条准则可能让“老手”架构师成竹在胸,而不是一头雾水
  • 遵循这条准则可能让“老鸟”架构师对症下药,而不是贪大求全

复杂性起源

高性能

软件系统中高性能带来的复杂度次要体现在两方面,一方面是 单台计算机外部为了高性能带来的复杂度 ;另一方面是 多台计算机集群为了高性能带来的复杂度

单机复杂度

  • 操作系统和性能最相干的就是过程和线程
  • 如果咱们要实现一个高性能的软件系统,须要思考如多过程、多线程、过程间通信、多线程并发等技术点,而且这些技术并不是最新的就是最好的,也不是非此即彼的抉择。

集群复杂度

  • 任务分配,负载平衡
  • 工作合成,微服务

    • 简略的零碎更加容易做到高性能
    • 能够针对单个工作进行扩大

指标

掂量软件性能包含了响应工夫、TPS、服务器资源利用率等主观指标

高可用

零碎无中断地执行其性能的能力,代表零碎的可用性水平,是进行零碎设计时的准则之一。
零碎的高可用计划形形色色,但万变不离其宗,实质上都是通过“冗余”来实现高可用。

  • 高性能减少机器目标在于“扩大”解决性能;
  • 高可用减少机器目标在于“冗余”处理单元。

计算高可用

“计算”指的是业务的逻辑解决。计算有一个特点就是无论在哪台机器上进行计算,同样的算法和输出数据,产出的后果都是一样的

存储高可用

  • 整个零碎的高可用设计关键点和难点就在于“存储高可用”。存储与计算相比,有一个实质上的区别:将数据从一台机器搬到到另一台机器,须要通过线路进行传输。
  • 存储高可用的难点不在于如何备份数据,而在于如何缩小或者躲避数据不统一对业务造成的影响。

高可用状态决策

无论是计算高可用还是存储高可用,其根底都是“状态决策”,即零碎须要可能判断以后的状态是失常还是异样,如果呈现了异样就要采取行动来保障高可用

  • 独裁式
  • 协商式
  • 专制式

可扩展性

可扩展性是指,零碎为了应答未来需要变动而提供的一种扩大能力,当有新的需要呈现时,零碎不须要或者仅须要大量批改就能够反对,无需整个零碎重构或者重建。
设计具备良好可扩展性的零碎,有两个根本条件:

  • 正确预测变动

    • 准则:只预测 2 年内的可能变动,不要试图预测 5 年甚至 10 年后的变动。
  • 完满应答变动

    • 计划一:提炼出“变动层”和“稳固层”,核心思想是通过变动层来隔离变动
    • 计划二:提炼出“形象层”和“实现层”,核心思想就是通过实现层来封装变动。
    • 准则:1 写 2 抄 3 重构准则

其余起源

老本

往往只有“翻新”能力达到低成本指标

  • 引进新技术
  • 自研新技术

低成本实质上是与高性能和高可用抵触的,所以低成本很多时候不会是架构设计的首要指标,而是架构设计的附加束缚。

平安

  • 性能平安:其实就是“防小偷”
  • 架构平安:就是“防匪徒”

规模

  • 规模带来复杂度的次要起因就是“质变引起量变”
  • 数据越来越多,零碎复杂度产生量变

架构设计准则

适合准则,“适合优于业界当先”

不适宜的状况

  • 没那么多人,却想干那么多活
  • 没有那么多积攒,却想平步青云
  • 没有那么卓越的业务场景,却空想灵光一闪成为蠢才

简洁准则,“简洁优于简单”

简单的体现

  • 构造的复杂性

    • 景象

      • 组成简单零碎的组件数量更多
      • 同时这些组件之间的关系也更加简单
    • 问题

      • 组件越多,就越有可能其中某个组件呈现故障
      • 某个组件改变,会影响关联的所有组件
      • 定位一个简单零碎中的问题总是比简略零碎更加艰难
  • 逻辑的复杂性

    • 单个组件承当了太多的性能
    • 采纳了简单的算法

演进准则,“演变优于一步到位”

对于软件来说,变动才是主题

软件架构设计其实更加相似于大自然“设计”一个生物,通过演变让生物适应环境,逐渐变得更加弱小

避坑

  • 时刻揭示本人不要贪大求全
  • 防止自觉照搬大公司的做法

最佳实际

  • 应该认真剖析以后业务的特点,明确业务面临的次要问题,设计正当的架构,疾速落地以满足业务须要
  • 在运行过程中不断完善架构,一直随着业务演变架构

架构设计流程

辨认复杂度

  • 将次要的复杂度问题列出来,而后依据业务、技术、团队等综合状况进行排序,优先解决以后面临的最次要的复杂度问题。
  • 设计的指标应该以峰值来计算。峰值个别取平均值的 3 倍,
  • 设计指标设定为峰值的 4 倍是依据业务倒退速度来预估的,不是固定为 4 倍,不同的业务能够是 2 倍,也能够是 8 倍,但个别不要设定在 10 倍以上,更不要一上来就依照 100 倍预估。

设计备选计划

新技术都是在现有技术的根底上倒退起来的。``

常见谬误

  • 设计最优良的计划
  • 只做一个计划

    • 弊病

      • 心里评估过于简略,可能没有想得全面
      • 繁多方案设计会呈现适度辩护的状况,
      • 架构师再怎么牛,教训常识和技能也有局限
    • 实际

      • 备选计划的数量以 3 ~ 5 个为最佳
      • 备选计划的差别要比拟显著
      • 备选计划的技术不要只局限于曾经相熟的技术
  • 备选计划过于具体

    • 消耗了大量的工夫和精力
    • 将注意力集中到细节中,疏忽了整体的技术设计,导致备选计划数量不够或者差别不大。
    • 评审的时候其他人会被很多细节给绕进去,评审成果很差。
    • 正确的做法是备选阶段关注的是技术选型,而不是技术细节,技术选型的差别要比拟显著

评估和抉择备选计划

常见指导思想

  • 最简派
  • 最牛派
  • 最熟派
  • 领导派

评估策略

  • 列出咱们须要关注的品质属性点,而后别离从这些品质属性的维度去评估每个计划,再综合筛选适宜过后状况的最优计划
  • 常见的计划品质属性点有:性能、可用性、硬件老本、我的项目投入、复杂度、安全性、可扩展性等
  • 通常状况下,如果某个品质属性评估和业务倒退有关系(例如,性能、硬件老本等),须要评估将来业务倒退的规模时,一种简略的形式是将以后的业务规模乘以 2 ~4 即可,如果当初的基数较低,能够乘以 4;如果当初基数较高,能够乘以 2。
  • 即架构师综合以后的业务倒退状况、团队人员规模和技能、业务倒退预测等因素,将品质属性依照优先级排序,首先筛选满足第一优先级的,如果计划都满足,那就再看第二优先级……以此类推。

具体设计方案

具体设计方案阶段可能遇到的一种极其状况就是在具体设计阶段发现备选计划不可行。

  • 架构师岂但要进行备选方案设计和选型,还须要对备选计划的要害细节有较深刻的了解
  • 通过分步骤、分阶段、分系统等形式,尽量升高计划复杂度,计划自身的复杂度越高,某个细节颠覆整个计划的可能性就越高,适当升高复杂性,能够缩小这种危险。

reference

  1. 从 0 开始学架构

正文完
 0