分享

浅谈“架构设计演化”

 kaller_cui 2020-05-19


单体架构
单体架构,是指由一台或多台计算机组成中心节点。将数据集中存储于这个中心节点中,并且整个系统的所有业务功能也均在此集中处理。也就是说,在这种架构下,每个终端或客户端机器仅仅负责数据的录入和输出,而数据的存储与控制处理完全交由单体系统来完成。
1.1
特点:“三集中”
  • 业务集中

    业务集中,指的是所有业务都统一处理。这样做的好处是,业务较较容易做到规范、也比较容易被监管,进而控制风险。在很多传统金融企业中,这样的架构设计颇为常见。

  • 计算集中

    计算集中,指的是所有对数据的加工处理逻辑,都是集中完成的。当然,这也是后来这种架构方式,饱受争议之处。随着业务规模的增加,对计算能力要求突增,这种计算集中的方式较难做到扩展。

  • 数据集中

    数据集中,指的是所有相关数据都统一存储,集中访问。

1.2
主要痛点
  • 研发成本高

    因为是单体应用,即使应用间存在功能重叠,也很难实现共享。一般不存在业务系统间的互相调用,使用什么功能就本地开发完成,不依赖其他应用。当有频繁的需求变更时,需要重新编码、测试,完成开发全流程,很难做到快速迭代。因对现在的快速业务创新及敏捷交付的需求,很难满足。

  • 维护困难

    这类系统一般是是通过链条状的本地调用完成,往往是由一个人或团队负责开发和维护。随着业务的发展和需求变化,本地代码在不断的迭代和变更,最后形成了一个个垂直的功能孤岛,只有原来的开发者才理解接口调用关系和功能需求,一旦原有的开发者离职或者调到其他项目组,这些功能模块的运维就会变得非常困难。随着业务的发展和功能膨胀,这种架构很容易发生腐化现象。

  • 单点故障

    这类设计的可靠性差,存在单点故障风险。如发生某个应用BUG,可能会波及整个系统的使用,造成全局性的影响。

  • 扩展性差

    可伸缩性差:水平扩展只能基于整个系统进行扩展,无法针对某一个功能模块按需扩展。

分离架构
为了应对传统单体架构的问题,一般会采用拆分的策略。其核心就是降低软件的复杂性,减少开发工作量,从而降低开发成本,提高软件生产率。'分而治之'的结论,把复杂的问题分解为很多容易解决的小问题,原来的问题也就容易解决。
2.1
拆分方式

针对单体的拆分,可以遵从不同的逻辑及角度,

  • 业务角度

    从业务角度出发,按照不同的思路和粒度来拆分软件系统,就会得到不同的架构。

  1. 面向流程拆分:将整个业务流程拆分为几个阶段,每个阶段作为一部分。

  2. 面向服务拆分:将系统提供的服务拆分,每个服务作为一部分。

  3. 面向功能拆分:将系统提供的功能拆分,每个功能作为一部分。

    理解这三种思路的关键就在于如何理解'流程'、'服务'、'功能'三者的联系和区别。从范围上来看,从大到小依次为:流程 > 服务 > 功能。

  • 技术角度

    按照其实现,梳理和抽象出核心应用、公共应用,并作为独立模块存在。其中分层架构就是很常见的架构模式。按照分层架构进行设计时,根据不同的划分维度和对象,可以得到多种不同的分层架构。例如典型的C/S架构、B/S架构,其划分的对象是整个业务系统,划分的维度是用户交互,即将和用户交互的部分独立为一层,支撑用户交互的后台作为另外一层。

2.2
拆分原则:耦合与内聚

拆分出来的部分,可称为子系统或模块,其应完成一个相对对立的功能,并且与其他子系统/模块之间的关系很简单。其独立性是模块化、抽象、信息隐藏和局部化概念的直接结果,具有独立模块的软件容易开发、测试和维护。其独立性通过两项质量标准来衡量:耦合和内聚。

  • 耦合

    衡量不同模块间相互依赖的紧密程度。也叫块间联系。它是对一个软件结构内不同模块之间互连程度的度量。它取决于各个模块之间接口的复杂程度、进入或访问一个模块的点以及哪些信息通过接口传递。在设计上,应该追求“低耦合”,即拆分单元之间应该是业务隔离性比较大的,相互依赖度不高。

  • 内聚

    衡量一个模块内部各元素彼此结合的紧密程度。在设计上,需要追求“高内聚”,即划分单元的业务边界清晰,其内部的业务相关性很高、依赖性很高的。

2.3
主要痛点
  • 研发成本高

    这种方式,依然存在代码到处拷贝的问题。为了实现某单一功能(例如数据库访问),不得不在各处自己来实现。这无形中导致了代码的拷贝。

  • 复杂度扩散

    因各部分独立实现,当面临同一技术问题时,不得不都要去考虑。例如随着数据量增大、并发访问越来越高,用户的数据库访问成为瓶颈。此时可考虑通过增加缓存来降低读压力,对于这一架构上的调整,各业务线都需要关注其导致的复杂性。

  • 业务耦合度高

    如业务系统间复用了部分代码,则如果业务A需要升级,业务B将不得不面临被动升级的窘境。虽然可以通过拷贝代码方式解决,但又会造成代码冗余等问题。

  • 故障隔离性差

    如某业务系统出现问题,将很有可能会影响其关联调用的其他业务系统,进而导致更多的业务线受影响。此外,从数据库层面也存在类似问题,因各业务系统复用同一数据库,当某性能较差的语句拖垮整个数据库时,影响的可能是所有业务线。

    上述问题的核心是没有独立的服务层。

服务化(SOA)

为应对上述的问题,可将业务功能都独立成服务。服务就意味着要对外提供开放的能力,当其他系统需要使用这项功能时,无须定制化开发,直接引用即可。这种架构方式,可简称为SOA。SOA的全称是Service Oriented Architecture,中文翻译为'面向服务的架构'。SOA的出现,解决了企业内部多种业务系统的整合,这些系统可能异构、实现技术不同,但均可通过服务化完成整合,提高了业务系统的建设效率。

3.1
SOA特性
  • 面向服务的分布式计算

  • 服务间松散耦合

  • 支持服务的组装

  • 服务注册与自动发现

  • 以服务契约方式定义服务交互方式

3.2
SOA难点:松耦合

松耦合的目的是减少各个服务间的依赖和互相影响。因为采用 SOA 架构后,各个服务是相互独立运行的,甚至都不清楚某个服务到底有多少对其他服务的依赖。如果做不到松耦合,某个服务一升级,依赖它的其他服务全部故障,这样肯定是无法满足业务需求的。但实际上真正做到松耦合并没有那么容易,要做到完全后向兼容,是一项复杂的任务。

3.3
SOA模式
  • 中心化(ESB模式)

    ESB的全称是Enterprise Service Bus,中文翻译为'企业服务总线'。ESB将企业中各个不同的服务连接在一起。因为各个独立的服务是异构的,如果没有统一的标准,则各个异构系统对外提供的接口是各式各样的。SOA使用ESB来屏蔽异构系统对外提供各种不同的接口方式,以此来达到服务间高效的互联互通。ESB这样一个中心服务总线,提供了对各种技术接口(HTTP、Socket、JMS、JDBC等)的适配接入、数据格式转换、数据裁剪、服务请求路由等功能。核心目的是让企业客户能基于这些SOA的产品实现系统间的互联互通,同时提高开发集成效率,更快地实现SOA项目的落地。这一架构解决的根本诉求是实现异构系统之间的交互。

  • 去中心化

    去中心化除了对SOA特性的实现和满足外,相比'中心化'的不同主要就是服务提供者和服务调用者之间在进行服务交互时无需通过任何服务路由中介,避免因为'中心点'带来的平台难扩展的问题及潜在的雪崩风险。但对于不同技术接口的支持、数据格式转换、服务动态路由等功能没有前者好,更多需要依靠服务应用的编写来满足这样的需求。

对比两者

  • 传统ESB模式的服务调用方式是,每一次服务的调用者要向服务器提供者进行服务交互请求时都必须通过中心的ESB来进行路由。经过服务总线路由过的服务交互,共出现4次网络会话创建和数据传输。而通过'去中心化'服务架构中的服务交互,一次服务的调用只有2次网络会话创建和数据传输,网络开销降低一半。从逻辑上看,所有服务调用都通过服务总线,服务总线的访问和计算压力都会非常大。另外,所有业务都通过服务总线的方式,则服务调用量比较大,所需的网络带宽要求非常高,甚至会出现超过目前网络设备的能力范围。
  • '中心化'架构可能给平台带来灾难性的'雪崩'效应。且一旦遇到雪崩之后,故障恢复的时间和成本都非常高昂。正因为雪崩隐患存在,某种程度上束缚了中心化服务框架的平台扩展能力。也就是说,增加中心点企业服务总线实例的节点数量,并不能线性扩展平台的服务能力。'去中心化'服务框架可以避免因为个别问题波及整个平台的业务受影响,最多也只是部分服务出现问题,就算出现问题也更容易定位问题和故障恢复。
微服务
微服务架构,是近些年来颇为流行的一个架构方式。从我来看,它更多的是服务化适应互联网化的产物,而不是取代服务化。下述内容摘自极客时间-李运华的课程《从0开始学架构》。
4.1
对比:SOA vs 微服务

  • 服务粒度

    整体上来说,SOA的服务粒度要粗一些,而微服务的服务粒度要细一些。

  • 服务通信

    SOA采用了ESB作为服务间通信的关键组件,负责服务定义、服务路由、消息转换、消息传递,总体上是重量级的实现。微服务推荐使用统一的协议和格式,例如,RESTful协议、RPC协议,无须ESB这样的重量级实现。

  • 服务交付

    SOA对服务的交付并没有特殊要求,因为SOA更多考虑的是兼容已有的系统;微服务的架构理念要求'快速交付',相应地要求采取自动化测试、持续集成、自动化部署等敏捷开发相关的最佳实践。如果没有这些基础能力支撑,就难以达到快速交付的要求,部署的成本呈指数上升。

  • 应用场景

    SOA更加适合于庞大、复杂、异构的企业级系统,这也是SOA诞生的背景。这类系统的典型特征就是历时间久、技术栈不同、来源各异,无法大规模优化或重构。因为成本和影响太大,只能采用兼容的方式进行处理。微服务更加适合于快速、轻量级、基于Web的互联网系统,这类系统业务变化快,需要快速尝试、快速交付;同时基本都是基于Web,虽然开发技术可能差异很大,但对外接口基本都是提供HTTP RESTful风格的接口。

4.2
微服务特点
  • 分布式服务组成的系统

  • 按照业务而不是技术来划分组织

  • 做有生命的产品而不是项目

  • 智能化服务端点与傻瓜式服务编排

  • 自动化运维

  • 系统容错

  • 服务快速演化

4.3
“微服务化”带来的问题
  • 服务管控

    在分布式服务体系下,服务链路跟踪、链路分析、实时业务指标的监控等问题,也都是实现微服务架构时一定会面临的问题,扩大到更大范围就是整体服务平台的管控能力。

  • 分布式事务

    需要针对业务的需求在事务一致性和性能间做好平衡,一套稳定、成熟的分布式事务解决方案也是构建微服务框架首先要考虑的技术问题。

  • 自动化运维

    微服务化后,较之前的部署方式,从服务器的数量以及服务交互复杂程度上都上升一个数量级,原有运维工具和平台是否能够支撑需要好好考虑。

  • 服务设计

    微服务中服务边界的划分一定是从业务的维度,以什么样的服务颗粒度定义服务?以什么样数据模型支撑服务能力的线性扩展?如何设计服务具有很好的业务前瞻性?

  • 组织架构

    服务强调持续的演变,需要组建对应的组织或者对现有的组织架构进行调整,围绕以服务为中心的持续运营,这对很多企业原有的信息中心架构师不小的冲击。

4.4
微服务陷阱
  • 服务划分过细,服务间关系复杂

    服务划分过细,单个服务的复杂度确实下降了,但整个系统的复杂度却上升了,因为微服务将系统内的复杂度转移为系统间的复杂度了。从理论的角度来计算,n个服务的复杂度是n×(n-1)/2,整体系统的复杂度是随着微服务数量的增加呈指数级增加的。

  • 服务数量太多,团队效率急剧下降

    微服务的'微'字,本身就是一个陷阱,将服务拆分得很细。这样做给工作效率带来了明显的影响。一个简单的需求开发就需要涉及多个微服务。无论是设计、开发、测试、部署,都需要工程师不停地在不同的服务间切换。

  • 调用链太长,性能下降

    由于微服务之间都是通过HTTP或者RPC调用的,每次调用必须经过网络。在很多高性能业务场景下是难以满足需求的。为了支撑业务请求,可能需要大幅增加硬件,这就导致了硬件成本的大幅上升。

  • 调用链太长,问题定位困难

    系统拆分为微服务后,一次用户请求需要多个微服务协同处理,任意微服务的故障都将导致整个业务失败。然而由于微服务数量较多,且故障存在扩散现象,快速定位到底是哪个微服务故障是一件复杂的事情。

  • 没有自动化支撑,无法快速交付

    如果没有相应的自动化系统进行支撑,都是靠人工去操作,那么微服务不但达不到快速交付的目的,甚至还不如一个大而全的系统效率高。

  • 没有服务治理,微服务数量多了后管理混乱

    随着微服务种类和数量越来越多,如果没有服务治理系统进行支撑,微服务提倡的轻量化就会变成问题。如果以上场景都依赖人工去管理,整个系统将陷入一片混乱,最终的解决方案必须依赖自动化的服务管理系统。

发展趋势
5.1
领域驱动设计
领域驱动设计,简称DDD(Domain-Driven Design)。DDD是用来解决负责业务场景的。如果是简单业务场景,可使用简单的事务脚本解决;但对于复杂业务场景,这种方式就不再适用。因为一旦业务变得复杂,事务脚本就很难应对,容易造成代码的“一锅粥”,系统的腐化速度和复杂性呈指数级上升。目前比较有效的治理办法就是领域建模,因为领域模型是面向对象的,在封装业务逻辑的同时,提升了对象的内聚性和重用性,因为使用了通用语言,使得隐藏的业务逻辑得到显性化表达,使得复杂性治理成为可能。
5.2
业务服务化平台

业务服务中台,其本质是服务化的延伸。从早期的”API as Service”,过渡到” Product as Service”乃至” Solution as Service”。方式上仍然是通过拆分业务解决系统的复杂性,通过服务共享来提供可重用性,通过服务化来达到业务支持的敏捷性;通过统一的数据架构来消除数据交互的屏障。其核心在于业务支持能力的构建,重点是在于提高业务效率,提升业务创新力。

  • 从设计层面,主要是要遵循面向对象的分析和设计的方法。

  • 从运营层面,服务中心应该是一个完整的业务模型,要有数据运营和业务整合的价值。

  • 从工程层面,服务中心是基于分布式架构,解决了在大规模应用上的问题。

(欢迎大家加入数据工匠知识星球获取更多资讯。)

联系我们

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多