架构简洁之道之解耦模式

本文探讨了软件架构的三种解耦层次:源码层次、部署层次和服务层次。源码层次通过模块依赖管理实现变更隔离;部署层次引入独立部署单元,减少重构影响;服务层次通过网络通信实现强解耦,适合大规模分布式系统。随着项目发展,可能需要从单体逐步演进到微服务架构。选择最佳模式应考虑项目需求和成本,理想架构应允许灵活演进且保护大部分代码不受影响。
摘要由CSDN通过智能技术生成

源码层次:我们可以控制源模块之间的依赖关系,以此来实现一个模块的变更不会导致其他模块也需要变更或者编译。在这种解耦模式下,系统所有的组件都会在同一个地址空间内执行,它们会通过简单的函数调用来进行彼此的交互。 人们经常把这种模式叫作单体模式。从部署的角度来看,最后产生了一个单独的可执行文件。虽然这类系统的架构边界在部署过程中并不可见,但并不意味着它们不存在或者没有意义。因为即使最终所有的组件都被静态链接成了一个可执行文件,这些边界的划分对该系统各组件的独立开发也是非常有意义的。

部署层次: 我们可以控制部署单元(如DLL、共享库等)之间的依赖关系,以此来实现一个模块的变更不会导致其他模块的重新构建和部署。在这种模式下,大部分组件可能依然运行在同一个地址空间内,通过彼此的函数调用通信。但有一些别的组件可能会运行在同一个处理器下的其他进程内,使用跨进程通信,或者通过socket或共享内存进行通信。这里最重要的是,这些组件的解耦产生出许多可独立部署的单元。除此之外,这种部署层次解耦的组件与单体结构几乎是一样的,其所有函数仍然处于同一个进程、同一个地址空间中。

服务层次: 我们可以将组件间的依赖关系降低到数据结构级别,然后仅通过网络数据包来进行通信。这样的系统每个执行单元在源码层和二进制层都会是一个独立的个体,它们的变量不会影响共他地方(例如常见的服务或者微服务都是如此)。这是系统架构中最强的边界形式,一个服务就是一个进程。服务并不依赖于具体的运行位置,两个互相通信的服务可以处于单一物理处理器或多核系统的同一组处理器上,也可以彼此位于不同的处理器上。服务会始终假设它们之间的通信将全部通过网络进行。服务之间的跨边界通信相对于函数调用来说,速度是非常缓慢的,其往返时间可以从几十毫秒到几秒不等。因此我们在划分架构边界时,一定要尽可能地控制通信次数,在这个层次上通信必须能够适应高延时情况。除此之外,我们可以在服务层次上使用与本地进程相同的规则(低层模块成为高层模块的"插件"),即让比较低层次服务成为较高层次服务的“插件”。为此我们要确保高层次服务的源码中没有包含任何与低层服务相关的物理信息。

那哪个模式是最好的呢?

在项目早期很难知道哪种模式是最好的。事实上,随着项目的逐渐成熟,最好的模式可能会发生变化。例如,一个在某台服务器上运行良好的程序发展到一定程度,可能就会需要将其某些组件迁移到其他服务器上才能满足运行要求,当该系统中运行在一台服务器上时,我们进行源码层次的解耦就已经足够了。但在这之后,我们可能需要进行部署单元层次的解耦,甚至服务层次的解耦。

另一个解决方案是,默认就采用服务层次的解耦,这种做法的问题主要在于它的成本很高,并且是在鼓励粗粒度的解耦。毕竟,无论服务多么“微”,其解耦的精细度都可能是不够的。

服务层次解耦的另一个问题是不仅系统资源成本高昂,而且研发成本更高,处理服务边界不仅非常耗费内存、处理器资源,而且更耗费人力。

一个良好的架构应该能允许一个系统从单体结构开始,以单一文件的形式部署,然后逐渐成长为一组相互独立的可部署单元,甚至是独立的服务或者微服务最后还能随着情况的变化,允许系统逐渐回退到单体架构。并且一个设计良好的架构在上述过程中还应该能保护系统的大部分代码源码不受变更影响,对整个系统来说,解耦模式也应该是一个可选项。我们在进程大型部署时可采用一种模式,而在进行小型部署时则可能采用另一种模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一条叫做nemo的鱼

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值