软件架构到底是什么?每个人的理解可能不尽相同,下面举几个例子 维基百科的解释
软件架构是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。
IEEE结构定义:架构=系统宏观结构+系统组件关系+系统设计原则
the fundamental organization of a system, embodied in its components, their relationships to each other and the environment, and the principles governing its design and evolution --ANSI/IEEE
在我的理解里,我们可以将架构理解为对一个系统内部各部分及其相互作用的高度概括。这不仅包括了物理和信息的属性及其相互之间的配对,也涵盖了组成部分之间以及它们与环境之间关系的界定。通过遵循特定的原则对系统进行细分,架构使得不同参与者能够同时在各自的领域内高效工作,从而证明了有组织的创造过程远胜于无序的努力。软件架构的核心目的在于管理和降低系统的复杂性,实现业务逻辑与技术实现之间的清晰分离和解耦。
你所认知的架构和别人所说的架构可能是两码事。
不同职位对架构的视角是不一样的。比如,对老板来说,他看到的是企业架构;对产品同学,他看到的是产品业务架构;对于销售同学,他看到的是市场渠道架构;对开发人员,他看到的是服务技术架构;对于运维人员,他看到的是运维架构;而对于技术支持,他看到的是网络和物理架构。
企业架构(EA)关心的是企业的结构和行为,尤其是业务角色和流程、业务数据的创建和使用。它被定义为“为分析、设计、规划与实现企业而精心设计的实践过程,使用一个全面的方法来保障企业战略被成功地开发和执行。比如将架构原则和实践贯彻到业务、信息、流程和技术调整之中。”
企业架构将企业看做一个大型复杂系统,企业架构框架则提供工具和方法,帮助架构师聚焦到企业设计任务,并产出有价值的架构描述文档。
业务架构就是一张用于理解企业的蓝图,其中描绘了战略目标和战术需求之间的对齐关系,这张蓝图是用管理结构、业务过程、业务信息这类术语绘制的。
业务架构描述的是商业的真实一面,是一个跨学科的场景,专注于定义和分析 “业务是什么”、“怎么形成的”、“怎么组织的”、“怎么实现价值的”。这有助于设计具备竞争力的结构和流程,发挥优势,识别潜在的商业机会,进而推进业务的目标或推动创新。
8
物理架构涉及到软件组件在硬件资源上的部署和配置,包括但不限于特定的软硬件环境或云计算平台,比如亚马逊的AWS、微软的Azure和谷歌的GCP等。云服务提供了灵活的资源配置、自动扩展和高可用性等特性,让物理架构的设计和管理更加高效和灵活。物理架构需要确保软件能够在适当的硬件资源上运行,同时考虑到了系统的性能、可靠性、扩展性和安全性等关键因素。
在物理架构的设计过程中,需要考虑的元素包括数据中心的构建、网络的拓扑结构设计,以及网络分流器、代理服务器、Web服务器、应用服务器、报表服务器、集成服务器、存储服务器和主机等不同类型硬件的选择和配置。这些元素共同构成了支撑软件运行的基础设施框架。
下面举例一个网上看到的例子,是某银行系统的数据中心
软件架构的发展是随着互联网技术的提升、用户规模的激增、网络通信容量的倍增而逐步发生的。下面所列的几个阶段都是如此。
下面再以一个电子商务网站为例,详细展示web应用的架构演变过程。
这个时候一个web项目里包含了所有的模块,一个数据库里包含了所需要的所有表。
这时候网站访问量增加时,首先遇到瓶颈的是应用服务器连接数,比如,tomcat连接数不能无限增加,线程数上限受进程内存大小、CPU内核数等因素影响,当线程数到达一定数量,线程上下文的切换对性能的损耗会越来越严重,响应会变慢,通过增加web应用服务器方式的横向扩展对架构影响最小,架构升级成2.0版本。
随着网站访问量继续增加,应用服务器数量持续增加,数据库成了瓶颈,而数据库的最主要的瓶颈体现在两方面:
这时,数据库可以采用主从方式进行读写分离的方案,并且引入缓存机制来抗读流量,同时需要考虑业务的垂直拆分,架构升级成3.0版本。
这时候仍然是垂直架构,所有业务集中在一个项目里。项目维护、快速迭代问题会越来越严重,单个模块的开发都需要发布整个项目,项目稳定性也受到很大挑战,这是需要考虑业务的垂直拆分,需要将一些大的模块单独拆出来,架构升级成4.0版本。
随着业务量增大,一些核心系统数据库单表数量达到几千万甚至亿级,这时候对该表的数据操作效率会大大降低,并且虽然有缓存来抗读的压力,但是对于大量的写操作和一些缓存miss的流量到达一定量时,单库的负荷也会到达极限,这时候需要将表拆分,一般直接采用分库分表,因为只做分表的话,单个库的连接瓶颈仍然无法解决。
同时,为了进一步提升用户体验,加速用户的网站访问速度,会使用CDN来缓存信息,用户会访问最近的CDN节点来提升访问速度。
随着流量的进一步增大,这时候系统仍然会有瓶颈出现,以订单系统为例,单个机房的机器是有限的,不能一直新增下去,并且基于容灾的考虑,一般采用同城双机房的方式,机房之间用专线链接,同城跨机房质检的延时在几毫秒,此时的架构图如下:
由于数据库主库只能是在一个机房,所以仍然会有一半的数据库访问是跨机房的,虽然延时只有几毫秒,但是一个调用链里的数据库访问太多后,这个延时也会积少成多。其次这个架构还是没能解决数据库连接数瓶颈问题。
单元化方案。如下图,流量从接入层按照路由规则(比如以用户ID来路由)路由到不同单元,每个单元内都是高内聚,包含了核心系统,数据层面的分片逻辑是与接入层路有逻辑一致,也解决了数据库连接的瓶颈问题,但是一些跨单元的调用是无法避免的,同时也有些无法拆分的业务需要放在中心单元,供所有其他单元调用。
随着上面提到的软件架构的演进,加入更多的功能点,系统变得越来越复杂:各个模块(Module)间存在着各种微妙的依赖关系。系统的复杂性随着时间积累,对于程序员来说,修改系统时考虑周全所有的的相关因素变得越来越困难。这就会使软件开放进度变缓慢,并且引入 Bug,而导致会进一步延缓开发进度,增加开发成本。在任何一个系统的生命周期中,复杂性不可避免会增加;系统越大,需要更多的人开发,管理系统复杂性的工作就越困难。
系统的复杂性可能源于多个方面:
面对复杂性,我们需要采取动态和渐进的策略,不断地重新认识和优化系统,方法包括
总的来说,系统复杂性的管理是一个持续的过程,要求开发者不断地学习和适应,来有效地控制和减少复杂性。
关于架构选型还说一句,选择合适的架构是基于当前业务需求的一项关键决策。在确保业务需求得到满足的同时,架构设计需要保持适度的扩展性,避免不必要的过度设计。每一次架构的更新和升级,都旨在解决系统存在的瓶颈问题,以促进系统性能的提升和业务的顺畅运行。
不可否认的是,架构设计的确是一个比较复杂的任务。因为要设计一个合理的架构,需要拥有如下能力:
最后,没有最好的架构,只有最合适的架构。
在当前公司内部基建完善,宏观架构稳定的前提下,我们更多要关注的是每个服务内部的分层情况。 服务分层的关键是是边界划分,软件架构设计本身就是一门划分边界的艺术。
分层架构是软件设计中一种常见的模式,其主要目的是将软件划分为不同的层,每一层负责处理特定的任务或关注点。这种分离使得系统更加模块化,提高了代码的可维护性、可扩展性和可测试性。虽然不同的分层架构模式可能因时代背景和设计哲学的不同而有所区别,它们的共同点在于都试图通过分离关注点来简化软件系统的复杂性。以下是一些常见的分层架构模式:
这是最基本也是最广为人知、群众喜闻乐见的分层模式,通常包括:
由Robert C. Martin提出,旨在实现关注点分离,提高系统的独立性。整洁架构将系统分为多个圆环层(洋葱模型),每个层只能与相邻的内层进行通信。
葱架构强调核心代码的独立性,类似于整洁架构,但具有自己的特点。它由几个同心圆层组成,最内层是领域模型,外层依次是领域服务、应用服务和基础设施层。所有的外部请求都通过基础设施层进入,然后向内传递至核心领域逻辑。
六边形架构也称为端口和适配器架构,由Alistair Cockburn提出。它将应用分为内六边形和外六边形两层,这两层的职能划分如下
六边形架构各层的依赖关系与洋葱架构一样,都是由外向内依赖。 六边形架构的核心理念是:应用是通过端口与外部进行交互。它强调应用程序核心逻辑的独立性,使其与外部世界隔离。核心逻辑通过端口与外部世界交互,外部的交互则通过适配器来实现。这种架构使得应用程序可以独立于外部设备、数据库、Web接口等运行。
领域驱动设计(Domain-Driven Design,简称DDD)的核心战略在于明确区分问题域和解决方案空间(即应用架构),并通过业务逻辑的显性化来简化复杂的业务算法。DDD通过创建领域对象和采用统一语言,将抽象和复杂的业务逻辑转换为清晰的领域概念。这种方法不仅提高了代码的可读性,还降低了团队成员之间的沟通成本。
通过DDD的建模方法,可以更好地表达现实世界中的复杂业务,随着时间的推移,系统对实际业务的理解将不断深入,从而更清晰地通过代码描述业务逻辑。模型的内聚性增强了系统的模块化,提高了代码的可重用性。与传统的三层架构模式相比,DDD能够避免功能在各个服务中的重复散布,从而实现更高效的代码组织和业务逻辑表达。
使用分布式系统核心要解决的问题有两点。一是提高整体架构的吞吐量,服务更多的并发和流量,二是为了提高系统的稳定性,让系统的可用性更高。
下面这四项技术,即应用整体监控、资源和服务调度、状态和数据调度及流量调度,它们是构建分布式系统最最核心的东西。
在高并发场景,实现高可用的三板斧是缓存,限流和降级。实施这些策略需要精细的设计和周到的计划,包括但不限于对系统架构的深入了解、各服务之间依赖关系的明确、以及对故障发生时各种情景的预案。通过这种综合性的防御策略,可以有效地保护系统免受突发高并发事件的严重影响,从而维持服务的稳定性和可靠性。
在任何服务系统中,存在着一个最大承载量,一旦请求量超出这一界限,系统可能无法响应,甚至会发生故障。为了避免这种情况,引入了服务降级和流量控制机制。流量控制,简而言之,是一种在遇到高并发请求或突发流量峰值时,为了维持系统的运行稳定和服务的可持续提供,而采取的一种策略,该策略通过牺牲一部分请求处理或延迟部分请求的处理来实现。这种策略的核心目的是通过有效管理资源分配和请求处理速率,防止系统过载。除了技术层面的措施,有效的流量控制还需要考虑到业务优先级,确保关键服务的高可用性。在设计限流策略时,需要综合考虑系统架构、业务需求和用户体验等多方面因素,以达到既保障系统稳定性,又尽可能满足用户需求的目的。
降级操作是在检测到系统关键组件故障或是响应时间过长时,暂时关闭一些非核心业务,保证系统能够继续提供最主要的服务功能。
熔断机制像是一个自我保护机制,当系统检测到某个服务异常(如失败率过高)时,会自动切断该服务的调用,防止错误进一步扩散。
负载均衡是一种技术策略,旨在通过将工作负荷(如数据处理任务和网络请求)均匀分配到多个处理单元(比如多台服务器或不同的系统组件)上,以优化资源利用、提高系统整体性能、增强系统的可用性并促进系统的横向扩展能力。这种方法不仅可以提升处理效率,还能避免因单个节点过载而导致的性能瓶颈或系统崩溃,从而确保服务的持续可用和响应速度。
在实现负载均衡时,可以采用多种技术和策略,如DNS轮询、IP哈希分配、最少连接数分配等,每种方法都有其特定的适用场景和优势。例如,DNS轮询简单易实施,适合于请求独立且服务器性能相近的场景;而IP哈希分配则可以保证来自同一客户端的请求被分配到同一个服务器,适合需要会话保持的应用。
此外,现代的负载均衡器不仅仅在于分配负载,它们还具备高级功能,如自动健康检查、SSL终端处理、攻击防护等,这些功能进一步增强了系统的稳定性和安全性。通过动态地管理和调整资源分配,负载均衡器能够确保系统即使在面对高并发请求、节点故障或其他不稳定因素时,也能保持高效和稳定的运行。
负载均衡的实施,对于构建高性能、高可用和易于扩展的系统至关重要。它不仅可以提高系统的处理能力和响应速度,还能提升系统的容错能力和灵活性,是实现服务稳定运行和支持业务增长的关键技术之一。
缓存可以提高系统的响应速度和
一般通过消息队列实现削峰的能力,可以增加系统的吞吐量。
应用层的自动化运维需要基础层的调度支持,也就是云计算 IaaS 层的计算、存储、网络等资源调度、隔离和管理。有了 DevOps 后,我们就可以对服务进行自动伸缩、故障迁移、配置管理、状态管理等一系列的自动化运维技术了。分布式系统可以更为快速地更新服务,但是对于服务的测试和部署都会是挑战。所以,还需要 DevOps 的全流程,其中包括环境构建、持续集成、持续部署等。
目前,团队内部从以下四个方面评价团队的技术。
本文作者:sora
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!