架构设计目的


了解了架构是什么,那就想想为什么需要软件架构。

随着互联网项目越来越庞大,需求越来越多也越来越复杂。在计算机软件的发展史中可以看出,软件的发展史其实就是一直与“复杂度”作斗争,架构的出现也不例外。所以,架构出现的目的就是为了解决这些复杂度而提出的方案。一句话来说: 架构设计的主要目的就是为了解决复杂度带来的问题

在进行架构设计时,想想这句话,可以让新手架构师心里有数,而不是怎么牛逼怎么来。也可以让有经验的架构师有舍有得,而不是贪大求全。

复杂度

既然架构设计是为了解决复杂度带来的问题。那么,什么是复杂度?他是怎么出现的?

个人理解,软件复杂度就是需求不断的变化,变大所带来的结果。一般会从以下方便带来复杂度

  • 高性能
  • 高可用
  • 可扩展
  • 成本
  • 安全

高性能

人们对性能的追求是一直在持续的。从蒸汽火车到高铁,从第一代iPhone到iPhone11,从电子管计算机到超大规模集成电路。当然技术的发展带来了性能提升,但是不一定会带来复杂度的提升。例如从磁盘到SSD,从几十KB的网络到移动网络,这些并对我们没有带来复杂度的增加,只有新的技术替代旧的技术,我们直接使用新技术即可。只有那些不是替代旧技术,而是开辟了新的领域的技术,才会带来复杂度。好比在出行方面,汽车无法替代火车,火车无法替代飞机。这样会使得我们在如何选择出行方式时,会带来复杂度。价格啊,舒适度啊,速度啊之类的我们都需要考虑。

软件系统中高性能带来的复杂度主要体现在两个方面

  • 单台计算机内部为了高性能带来的复杂度。
  • 多台计算机集群为了高性能带来的复杂度。

单机复杂度主要在多进程、多线程、进程间通信、多线程并发等,这些技术并不是最新的就是最好的,也不是非此即彼的选择。在架构设计中,需要花费较大的精力来结合业务判断,选择,这个过程也同样很复杂。就好比,Nginx可以多线程,可以多进程提高性能,Redis是用单进程提高性能,Memcache使用多线程提高性能。他们虽然都能提高性能,但是内部实现差异却很大。

集群复杂度是我们的重点讨论对象,就好比春节微信抢红包,阿里双11剁手节。面对这种复杂的业务,单机是无论如何也无法支撑的,必须采用集群,增加机器的方式解决,但是通过大量的机器来提高性能,并不仅仅是增加几台机器那么简单,让多台机器配合工作达到高性能的目的,是一个复杂的任务。

业界常见的让多个机器相互协作的方式有以下几种

  1. 任务分配,意思是将每台机器都可以完成的任务,不同的任务分配到不同的机器上执行。但是服务器的增加也带来了复杂度的问题,示意图如下

1台服务器变成2台服务器后,架构上明显复杂了很多,主要体现在

  • 需要添加一个任务调度器,可以是Nginx、F5、交换机等。选择合适的任务调度器也是一件复杂的事情,需要考虑性能,成本,可维护性等之类的因素。
  • 任务调度器与服务器之间需要有合适的连接方式,选择合适的连接方式也是一件复杂的事情,并且还要对连接方式进行管理,如连接中断之后如何恢复等。
  • 任务调度器还需要增加调度算法,是轮询,还是权重,又或者是一致性哈希。这也是需要考虑的一件事情,选择合适的算法也是一件复杂的事情。
  • 假设随着任务越来越多,单台任务调度器也可能会带来性能瓶颈问题,所以任务调度器也需要考虑集群。任务调度器变成了集群方式,同时也就意味着需要将不同用户分配到不同的任务调度器上,这也需要选择一个合适的方案,DNS轮询,CDN分发等。
  • 随着任务调度器的增多,服务器的增多。任务调度器和服务器的状态管理,故障恢复处理等复杂度也会大大的提升,同时服务器的成本也是个问题。
  1. 任务分解
    通过任务分配的方式可以解决单台机器性能瓶颈的问题,但是业务本身越来越复杂,单纯的增加机器的收益也会越来越低。这时候就需要任务分解来解决问题,我们可以将任务分解成不同的子任务。假设一个天猫系统的示意图如下

通过上面架构示意图可以看出,后台架构从逻辑上将各个业务拆分成了订单、购物车、商品、登录、其他等子业务。通过这种方式,把一个庞大的业务系统单个需要多个系统配合的业务系统。从业务角度上看,任务分解功能并不会减少功能,也不会减少代码量(事实上也可能会增多代码量),那为什么就可以提升性能了呢?主要有下面几个因素

  1. 越是简单的系统更容易做到高性能,系统简单,影响的功能点少,更容易有针对性的进行优化。
  2. 可以针对单个任务扩展,拆分之后,这个系统的瓶颈更容易被发现,发现之后可以在不影响其他子系统的情况下进行性能优化或提升,风险会小很多。

注意,并不是拆分的越细越好,拆分的越细,反而性能还会下降。拆分之后从原来的系统内函数调用,变成了网络远程调用。系统间的调用频率会增高,会降低整体的性能。所以,对于架构师来说,如何把握好这个粒度就非常关键了。

高可用

高可用就是指“系统无中断的运行”,代表系统的可用性成都,是进行系统设计时的准则之一。

首先无中断是个难点,因为不可能做到无中断运行的,硬件故障,软件bug,硬件老化等。除去这些,还需要考虑天灾,事故等因素也会让系统中断。所以,高可用的方案有很多,其本质就是通过冗余来实现高可用。简单来说,一台服务器不够就两台,两台服务器不够就三台;一个机房可能会断电,就部署两个机房;四川有可能会地震,北京在部署一个;但是如果世界末日的话???

高可能用高性能有着本质的区别,高性能增加机器在于扩展处理性能;高可用增加机器的目的在于冗余处理单元。

通过冗余增强了可用性,但同时也带来了复杂度。通过不同的场景来分析一下

  • 计算高可用。计算是指业务的逻辑处理。计算有一个特点就是无论在哪台机器上,同样的算法的输入数据,输出结果都是一样的,所以这些机器可以相互替代。计算高可用的复杂度与高性能增加机器的复杂度相似,也是通过添加任务调度器所产生的复杂度。
  • 存储高可用。存储高可用与计算高可用相比,有一个本质的区别:将数据从一台机器传输到另一台机器,需要一定的时间,耗时随着两个机器的物理距离成正比。不稳定的情况下会达到1s多。但是对于高可用系统来说,这个时间就有点长了,这就意味着在某个时间点上,这些机器的数据会不一致。数据不一致会导致逻辑不一致,最终导致业务表现不一样。如何解决这个问题也是存储高可用带来的复杂度,所以存储高可用的难度在于如何减少或者规避这种数据不一致所带来的业务影响。
  • 高可用状态决策。无论是计算高可用还是存储高可用,基础都是“状态决策”,即系统能够判断当前的状态是不是正常的还是异常的。如果状态判断错误,后续的行动无论怎么处理都是无意义的,同时状态的判断也不可能做到完全正确。

可扩展性

可扩展性就是系统为了应对将来的需求变化而提供的扩展能力,有新需求出现时,可以需要修改或者少量的修改可以达到目的。

有句谚语:唯一不变的就是变化。软件开发也是,软件系统不像建筑系统一样完工了就不会改变。软件系统需要不断的演进,演进的过程中也不能需要太大的成本。也不可能为了一个需求推翻现有的系统,所以尽量减少改动是最好的。我们需要正确的预测变化和封装变化。

  • 预测变化,在架构设计时,架构师需要能够预测到那些地方后期可能需要变动,但是到底是预测,也不可能100%预测到。预测变化的复杂在于
    • 不能每个设计点都需要考虑可扩展性。
    • 不能完全不考虑可扩展性。
    • 所有的预测都可能存在出错。
  • 应对变化,我们可以将变化封装一个变化层,将不变的封装在一个稳定层。但是这种剥离变化层和稳定层也会带来复杂度。
    • 需要区分变化层和稳定层
    • 需要设计层与层之间的接口

低成本

低成本与高性能,高可用是冲突的。高可能和高可用是增加机器来解决的,增加机器就以为成本会变高。所以低成本不会是架构设计的首要考虑目标,是架构设计的附加约束。低成本的复杂度在于需要创新达到低成本的目的,开创一个新的技术领域来解决现有的问题,这通常会是大公司作出的方案。一般情况我们还是会选择使用新技术来降低成本。

无论是使用新技术还是开发新技术,都是一个复杂的事情。使用新技术需要了解这个技术,能不能运用到我们先有的项目中。创造新技术需要投入大量的人力还财力,并且与旧技术相比,需要有质的飞跃。

安全

安全本来就是复杂又庞大的领域,而且没有绝对的安全。从技术角度来说,安全可以分为两类,功能安全和架构安全

  • 功能安全。能够抵御常见的XSS攻击,CSRF攻击,SQL注入,密码破解等。黑客会利用这些漏洞潜入系统,偷取你的数据。通常需要在编码的时候注意,与架构设计无关。功能安全本质就是“防小偷”
  • 架构安全,功能安全是“防小偷”,那架构安全则是“防强盗”。互联网时代,黑客会从各个地方对你发起恶意攻击。传统的架构安全主要是防火墙,但是防火墙性能一般,而且贵,所以一般公司不会选择堆防火墙来解决问题。互联网的架构目前来说没有太好的设计手段来时间,现在主要是靠运营商或者服务器厂商提供的带宽和流量清洗能力。

Author: Re:0
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Re:0 !
 Previous
架构设计原则 架构设计原则
从程序员到架构师,需要跨域一个鸿沟“不确定性”。在开发中,写出来的代码执行结果是确定的,但是对于架构来说,本质就是不确定的。同样的系统,A公司和B公司架构差异很大,但是都能运行。同一个方法,A方案也能做,B方案也能做,但是各有各的道理。相比
2022-04-28
Next 
软件架构基础 软件架构基础
“架构”到底指什么对于开发人员来说,架构是一个最常见不过的名词了: 给新员工介绍软件整体架构,参加架构设计评审,学习优秀的架构设计。那么深究一下架构是什么,很多人都回答不上来。 我们先理清以下的几个概念,再来回答架构是什么。
2022-04-26
  TOC