系列文章目录
第一章 系统架构的演进
本篇文章目录
- 系列文章目录
- 前言
- 一、原始分布式
- 二、单体系统时代
- 三、SOA时代
- 烟囱架构
- 微内核架构
- 事件驱动架构
- 四、微服务架构
- 五、后微服务时代
- 六、无服务时代
- 总结
前言
最近笔者一直在学习系统架构的相关知识,对系统架构的演进过程做了一番归纳整理。我们知道,如今流行的系统架构都不是突然出现的,而是随着互联网的发展,业务复杂度的提升,为了适应各种复杂场景逐步设计演化出来的。下面我将分析架构演进过程中出现的几种具有代表性的架构方式,他们为什么出现 ?解决了什么问题 ?又为什么会被淘汰?让我们带着疑问往下看。
一、原始分布式
原始分布式架构指的是早期的分布式系统设计,这些系统在20世纪70年代末至80年代初开始出现,那时计算机技术正处于从大型主机系统向个人计算机(微型机)转变的阶段。在这个时期,硬件资源相对有限,网络通信技术尚不成熟,因此分布式架构面临诸多挑战。以下是原始分布式架构的一些特点和问题:
-
硬件限制:
计算机硬件性能相对较弱,如16位处理器、低频CPU和有限的内存。
网络带宽和稳定性不高,通信延迟和数据传输速度是主要问题。 -
系统复杂性:
将单一的大型系统拆分为多个独立服务增加了系统的复杂性,需要解决服务间的协调和通信问题。
缺乏标准化的接口和通信协议,导致集成难度大。 -
容错性和可靠性:
在没有现代故障检测和恢复机制的情况下,系统对单点故障的容忍度较低。
数据一致性难以保证,尤其是在没有分布式事务支持的情况下。 -
编程模型:
编程模型相对简单,往往依赖于远程过程调用(RPC)或其他简单的消息传递机制。
缺乏现成的框架和工具支持,开发和维护成本较高。 -
安全性:
安全性不是最初设计的重点,随着网络的扩展,安全问题逐渐显现。 -
管理与监控:
系统管理和监控工具不发达,诊断和调试分布式问题困难。
原始分布式时代,最初的设计愿景是符合UNIX的分布式设计哲学:即保持接口与实现的简单性,比系统的任何其他属性,包括准确性、一致性、完整性都更加重要。
同时,在摸索过程中也得到了一个十分重要的教训:某个功能能够进行分布式,并不意味着其就应该进行分布式,强行进行分布式操作,只会自食苦果。
二、单体系统时代
这种架构是整个架构史上出现最早,使用范围最广,使用人数最多的架构风格了。无论你的业务有多复杂,都可以使用这种架构,只不过是性能、扩展性、可靠性、可维护性的问题。这种架构本身比较简单。需要说明的是,这种被称为单体架构的架构风格也是后来出现了微服务架构风格后才追认的,一开始根本就没有架构风格可言,也没有谁有概念去研究和区分架构风格。所有人都认为软件结构就应该是这样的,没有其他的方式,直到随着技术的发展,出现了性能瓶颈,单体架构变得越来越难用,使用这种架构的技术成本逐渐大到无法忍受时,才慢慢探索出了后来的架构风格。单体架构主要有以下几个特性:
-
整体性:应用程序的所有组件,如业务逻辑、数据访问和用户界面,都紧密集成在一个单一的可执行文件或部署单元中。
-
垂直结构:各组件通常按功能垂直划分,每个功能模块包含从用户接口到数据库访问的全部代码。
-
单一部署:修改任何部分功能都需要重新部署整个应用,因为所有组件都是相互依赖的。
-
简单易懂:由于结构相对简单,开发和维护相对直接,适合小型项目或初期快速开发。
-
局限性:随着系统复杂度增加,单体架构的可扩展性和灵活性会降低,更新和维护变得困难,可能导致“雪崩效应”。
-
数据库共享:通常所有组件共享同一个数据库,导致数据访问和事务管理复杂。
-
技术栈限制:通常整个应用使用同一种技术栈,难以引入新的技术或服务。
我们一般说的都是大型的单体架构应用,这种架构要求每一处代码,每一个组件设计都尽可能的完美、可靠,但是这种提升是有限度的,单体架构在大规模业务,超高并发的请求量下显得束手无策。
当然不是说单体架构就应该淘汰,完全否决。采用什么架构要根据场景来,一般规模较小的系统,采用单体架构是最合适的选择,复杂度不高,快速搭建出应用。
单体系统又叫"巨石系统",从名字上看好像是不可拆分的,但实际上并不是完全不可拆分。起码代码结构上可以按照不同的业务模块划分。即使是一个完整的单体应用,也可以部署多个副本系统,通过负载均衡技术来分摊流量压力。
单体系统真正的缺陷不是如何拆分,而是拆分后的自治、隔离。单体系统所有的代码都运行在一个进程内,所有模块、方法的调用都不需要考虑网络分区、对象复制等棘手的事和性能损失。在获得这些好处的同时,一旦代码出现缺陷,造成了资源的浪费,那就会导致整个应用崩溃,影响是灾难性的。这在大型互联网公司是不能忍受的。
三、SOA时代
首先介绍SOA架构出现前的三种常用的架构模式。
烟囱架构
烟囱架构设计是一种信息孤岛式的架构模式。指的是一种与其他相关信息系统完全没有互操作或者协调工作的设计模式。这样的系统其实并没有什么架构设计可言。主要特点如下:
-
独立开发和部署:每个应用程序都是独立设计、开发、部署和维护的,包括前端界面、后端逻辑、数据库等所有组件,形成一个个孤立的“烟囱”。
-
垂直整合:每个“烟囱”都是一个自给自足的系统,拥有自己的用户界面、业务逻辑层、数据访问层及数据库,不同系统间很少有共享的组件或服务。
-
资源重复:由于每个烟囱式系统都是独立的,可能会导致技术栈、硬件资源、甚至相同功能的代码重复,增加了维护成本和资源浪费。
-
扩展困难:当单个系统需要扩展时,通常需要对整个系统进行扩展,包括不直接相关的组件,这既昂贵又低效。
-
集成难题:烟囱式架构下的系统间集成较为困难,通常需要定制的接口或数据交换机制,这增加了系统间的耦合度和复杂性。
-
适应性差:面对快速变化的业务需求,烟囱式架构难以快速调整或新增功能,因为改动一个部分可能会影响到整个系统的稳定性和性能。
烟囱式架构在早期IT系统建设中较为常见,特别适合那些需求稳定、变更频率低的场景。然而,在当前快速迭代、高并发和需要高度灵活的业务环境下,烟囱式架构逐渐显现出其局限性,促使企业转向微服务、SOA等更灵活的架构模式。
微内核架构
微内核架构又叫插件式架构。这种架构比较好理解,就是把一些公用的基础服务、数据、资源整合到一起,提供一个被所有其他业务公用的核心依赖,其他的业务模块以插件的形式存在。这样也能可以提供可扩展、灵活的、天然隔离的功能特性。
事件驱动架构
这种架构是为了能让子系统互相通信,在这些子系统之间建立一套事件队列管道,来自系统外部的消息以事件的形式发送至管道中。各个子系统就从这个管道中订阅自己感兴趣、能处理的事件消息,亦可以自己发送新的事件到管道队列中去。这样一来,每个消息的处理者都是高度解耦独立的,同时又能够通过事件队列管道进行通信。
笔者经历过的一个项目是开发一个医院内部耗材管理软件。医院一般有很多个信息系统,比如his系统、电子病历系统、门诊系统,医疗设备管理系统等等,少的十几个,多的几十个。那这些系统之间要想建立联系,最直接的方式就是互相做接口通信,这个工作量是比较大的,很不灵活,而且这些系统有一些数据是公用的,比如医护人员账号,院内科室部门划分等,在每个系统上都要维护一次,有改动则每个系统都要自己添加一次。笔者开发的软件作为医院内部软件的一个子软件,自然避免不了和其他系统交互,获取基础数据。我遇到过有很多医院都有一个类似事件队列管道的基础服务中心组件,来承担者各个系统之间交互的中介者角色,每个系统都会发布一些事件消息到事件队列管道中去,以供其他系统订阅获取。
SOA架构的出现就是为了解决单体架构所不能解决的问题,譬如程序出错,获得自治与隔离的能力,实现技术异构等目标。SOA架构的几个特征如下:
-
服务松耦合:SOA强调服务之间的松耦合,意味着服务应当能够独立地修改和升级,而不影响其他服务,这促进了系统的灵活性和可维护性。
-
服务重用:通过将功能封装为服务,可以在不同应用程序和业务流程中重用这些服务,减少了重复代码,提高了开发效率。
-
标准化接口:服务之间通过标准化的协议和消息格式(如XML、JSON通过HTTP、SOAP或RESTful API)进行通信,降低了集成的复杂性。
-
基于业务功能的拆分:SOA鼓励根据业务功能而非技术界限来组织服务,使得架构更贴近业务需求。
-
服务注册与发现:通常使用服务注册表或服务目录来记录所有可用服务及其接口信息,便于服务的查找和调用。
-
支持异构环境:SOA架构可以跨多种技术和平台工作,支持不同编程语言和操作系统之间的互操作性。
-
治理和管理:SOA强调服务生命周期的管理和治理,包括服务的设计、实现、部署、监控和安全控制。
-
企业服务总线(ESB):虽然不是SOA的强制要求,但ESB常被用来作为服务间通信的中介,处理消息路由、协议转换、安全等问题,以简化服务集成。
SOA架构明确采用了SOAP作为远程调用协议,依靠SOAP协议族(WSDL、UDDI、和WS-*)来完成服务的发布、发现和治理;利用企业服务总线(ESB)的消息管道来实现各个子系统之间的交互,让各个子系统不需要直接相互依赖,通过ESB就可以实现相互通信,实现了服务之间的松耦合,为后面的服务编码,服务治理提供了良好的基础。
SOA架构不仅仅关注技术,还关注研发过程中涉及到的需求、管理、流程和组织。终极目标是想提供出一套自顶向下的研发方法论,所有的企业只需要根据SOA的理论思路,就可以解决软件开发中的所有问题。
但是SOA最终还是沉寂下去了,本质原因是它过于严格的规范定义带来过度的复杂性,构建在SOAP基础上的ESB、BPM、SCA、SDO等上层技术组件,使得其更加复杂。这就对开发人员有很高的要求,必须对这一套技术掌握很深才能进行软件开发工作。它适合实现多个异构大型系统之间的复杂集成交互,它不是一种普适性的软件架构解决方案,简单场景使用SOA架构又得不偿失,所以最终落幕了。
四、微服务架构
微服务架构将一个大型的应用程序拆分成一组小型、自治的服务。这些服务围绕着业务功能构建,可以通过轻量级通信机制(通常是HTTP RESTful API)相互通信。下面是微服务架构的一些核心特点和原则:
-
服务组件化:每个服务都是一个独立的业务功能单元,可以独立部署、扩展和维护。
自治性:服务之间相互解耦,每个服务都有自己的数据库和业务逻辑,可以独立开发、部署和扩展,互不影响。 -
基于接口通信:服务间通过定义良好的接口(通常是API)进行通信,接口协议通常是HTTP/REST或gRPC等。
-
去中心化治理:微服务架构鼓励去中心化的决策和数据管理,每个服务团队对他们的服务拥有完全的控制权。
-
持续集成与部署(CI/CD):采用自动化工具链来频繁且可靠地部署服务,支持快速迭代和故障恢复。
-
容错性:设计时考虑到服务可能会失败的情况,通过服务降级、熔断器模式等策略提高系统的整体可用性。
-
技术多样性:不同服务可以根据需求选择最适合的技术栈,不必拘泥于单一技术平台。
-
可伸缩性:由于服务是独立的,可以根据实际负载情况单独对某个服务进行水平或垂直扩展。
-
监控与日志:强调服务的可观测性,通过日志、跟踪和度量来监控服务的健康状况和性能。
微服务架构的优势在于提高了系统的灵活性、可维护性和可扩展性,但同时也带来了服务间的复杂协调、数据一致性挑战以及运维复杂度增加等问题。
微服务是从SOA演化来的,但笔者认为微服务和SOA是两种不同的架构风格,尽管他们的表现形式一致,但微服务没有统一的标准或规范,SOA却有严格统一的技术标准和规范。微服务对于服务的注册、治理、隔离、发现、负载均衡等有不同解决方案,没有统一技术标准,这带来了极大的自由度,对于普通开发者而言,微服务架构是十分友善的,灵活的架构设计,熟悉什么什么组件就用什么,但对于架构设计者来说就没那么友好了,需要架构师有较强的架构能力才能选择合适的架构,因为没有标准,需要根据不同的场景选择合适的解决方案。
五、后微服务时代
后微服务时代,这一概念虽然没有明确的定义边界,但可以理解为在微服务架构得到广泛应用并逐渐成熟之后,软件开发和架构设计领域的新趋势和思考。以下是几个可能标志着进入后微服务时代的特点和发展方向:
-
服务网格(Service Mesh): 随着微服务架构的复杂性增加,服务间的通信、监控、安全等问题日益凸显。服务网格作为一种基础设施层,解耦了服务间通信的逻辑,使得开发者可以更专注于业务逻辑,而不是服务治理本身。
-
无服务器(Serverless): 无服务器架构进一步抽象了计算资源,开发者无需关心底层服务器的运维,按需付费,自动扩展。这种模式降低了微服务的运维成本,使得开发者能够更加聚焦于业务代码。
-
函数即服务(Function as a Service, FaaS): 是无服务器架构的一个重要应用形式,允许开发者以函数为单位部署代码,非常适合事件驱动的场景。它使得服务粒度更加细小,响应更加迅速,成本也更为可控。
-
容器化与Kubernetes的普及: 容器化技术特别是Docker以及容器编排工具Kubernetes的广泛采用,为微服务的部署和管理提供了标准化的解决方案,提高了应用的可移植性和伸缩性。
-
面向领域的设计(Domain-Driven Design, DDD): 在后微服务时代,随着系统规模的扩大,DDD成为解决复杂业务逻辑设计的重要方法论。它强调通过深入理解业务领域,将大型系统拆分为多个上下文相关的微服务,每个服务专注于特定的业务领域。
-
API Gateway & API Management: 为了有效管理大量微服务之间的交互,以及对外暴露统一的API接口,API网关和API管理平台变得尤为重要。它们提供了流量控制、安全认证、协议转换等功能,简化了微服务架构的外部交互。
-
持续集成/持续部署(CI/CD): 高效的CI/CD流程是支撑微服务快速迭代的关键。在后微服务时代,更加自动化、智能化的CI/CD工具链成为标配,确保了从代码提交到生产部署的快速且可靠。
-
观察性(Observability): 随着服务数量增多,系统的可观测性变得至关重要。这包括日志、跟踪、度量等方面,帮助快速定位问题并优化系统性能。
后微服务时代更加强调在微服务基础上的优化、整合与智能化,以应对更加复杂多变的业务需求和技术挑战。
六、无服务时代
无服务器(Serverless)时代是指一种云计算的执行模型,其中开发者无需直接管理服务器或其运行环境,而是将重点放在编写代码和构建应用逻辑上。云服务商自动管理和动态分配计算资源,按需运行代码片段(通常称为“功能”)。以下是无服务器架构的几个核心特点:
-
自动扩展:根据应用的实际需求,云平台自动扩展计算资源,开发者无需预估或配置服务器容量。
-
按用量付费:用户只需为实际消耗的计算资源付费,而不需要为闲置时间支付费用,降低了成本。
-
高可用性与容错:云服务商负责底层基础设施的高可用性和容错设计,确保服务稳定运行。
-
快速部署与迭代:开发者可以迅速部署代码并进行迭代,缩短了从开发到生产的周期。
-
事件驱动:无服务器应用通常由外部事件触发(如HTTP请求、数据库更改、消息队列等),使得系统更加灵活和响应迅速。
-
减少运维负担:由于服务器管理任务由云服务商承担,开发团队可以专注于业务逻辑,减少了运维工作量。
代表性技术和服务包括AWS Lambda、Azure Functions、Google Cloud Functions等。无服务器架构正在推动软件开发进入一个更高效、灵活的新时代。
总结
架构的演进会是持续的,没有一种架构会一直存在下去,持续大规模使用,只能说在当前环境下适合采用什么样的架构,微服务和无服务之后可能还会出现其他的架构风格,但是每个阶段出现的架构都是值得我们去探索思考的,理解每种架构出现的意义和被淘汰的原因,才能更好解决眼下的软件开发问题,为未来架构演进寻找出路。