编辑
2026-05-10
记录知识
0

目录

前言
分层架构
C/S架构和B/S架构
MVC架构和MVP架构
分层架构的关键原则
分层架构的不足
SOA架构
Web Service的发展
SOA的核心概念
分层架构与SOA的比较
架构选择建议
总结
附录:Python 示例
参考资料

前言

相比于高性能、高可用架构模式在最近几十年的迅猛发展,可扩展架构模式的发展可以说是步履蹒跚。最近几年火热的微服务模式算是可扩展模式发展历史中为数不多的亮点,但这也导致了现在谈可扩展的时候必谈微服务,甚至微服务架构都成了架构设计的银弹——高性能也用微服务、高可用也用微服务,很多时候这样的架构设计看起来高大上,实际上是大炮打蚊子,违背了架构设计的"合适原则"和"简单原则"。

为了帮助你在实践中更好地进行可扩展架构设计,我将分别介绍几种可扩展架构模式。今天我先介绍传统的可扩展模式:分层架构和SOA。

分层架构

分层架构是很常见的架构模式,它也叫 N 层架构,通常情况下 N 至少是 2 层。例如 C/S 架构、B/S 架构,常见的是 3 层架构(如 MVC、MVP 架构)、4 层架构,5 层架构的比较少见,一般是比较复杂的系统才会达到或者超过 5 层,比如操作系统内核架构。

按照分层架构进行设计时,根据不同的划分维度和对象,可以得到多种不同的分层架构。

C/S架构和B/S架构

划分的对象是整个业务系统,划分的维度是用户交互,即将和用户交互的部分独立为一层,支撑用户交互的后台作为另外一层。

MVC架构和MVP架构

划分的对象是单个业务子系统,划分的维度是职责,将不同的职责分离到不同的层。例如经典的三层架构:

  • 展示层:负责用户页面设计,不同业务有不同的页面
  • 业务层:负责具体业务逻辑的处理
  • 数据层:负责完成数据访问

这种架构的好处在于:

  • 假设某天数据库从 MySQL 迁移到 MongoDB,只需要修改数据层,其他层无需改动
  • 如果要增加手机 App 访问,只需要增加新的展示层,无需修改业务逻辑

分层架构的关键原则

分层架构需要遵循禁止跨层访问的原则。展示层只能访问业务层,业务层只能访问数据层,数据层只能访问存储层。如果允许跨层访问,例如展示层直接访问存储层,那么存储层变更时会导致展示层也要跟着变动,失去了分层的意义。

分层架构的不足

分层架构的核心问题是不同层之间的边界比较模糊,边界一旦模糊,职责就难以明确区分。很多时候分层架构会演变为两层架构——业务和数据混杂在一起,失去了分层的意义。

SOA架构

SOA(Service-Oriented Architecture,面向服务架构)是一个古老的服务编排概念,早在 1996 年就被提出了,比微服务早了整整 20 年。然而 SOA 虽然发展了这么多年,却并没有取得特别广泛的应用,这其中有多方面原因。

Web Service的发展

2000 年左右,Web Service 概念被提出并开始蓬勃发展,SOA 也跟随 Web Service 的发展进入了第二个高潮期。当时 IBM、Oracle 等大厂都主推 Web Service,各种大会都在讲 Web Service,SOA 看起来前途无量。

然而,Web Service 最终并没有成为 SOA 的拯救者,原因在于:

ESB企业服务总线:ESB 是 SOA 实现的核心基础设施,但 ESB 本身成为了性能瓶颈。一个简单功能经过 ESB 转发后,性能可能降低 10 倍还多。更糟糕的是,ESB 本身成为了一个"中心",既没有实现真正的解耦,反而增加了系统的耦合度。

服务粒度问题:SOA 尝试将所有东西都定义为服务粒度,但有些业务功能其实不需要独立成服务,过度拆分反而导致系统复杂度急剧上升。

技术标准复杂:WS-*标准堆砌太多,学起来复杂,用起来更复杂。

SOA的核心概念

SOA 的核心概念包括:

服务:具有清晰定义边界的业务功能单元

服务注册与发现:通过注册中心管理服务位置和元数据

企业服务总线(ESB):负责服务路由、协议转换、消息传递

服务契约:预先定义的服务接口规范

SOA 的设计理念是"化繁为简",试图通过标准化的服务定义和编排来解决企业级系统的集成问题。但由于过度设计和复杂性,SOA 最终未能达到预期效果。

分层架构与SOA的比较

维度分层架构SOA
划分维度职责服务
耦合度层间解耦,层内耦合服务间解耦
扩展方式横向扩展整层纵向扩展单个服务
适用场景简单业务系统复杂企业系统
实现复杂度较低较高

架构选择建议

架构设计没有银弹,分层架构和 SOA 各有适用场景:

  • 如果系统规模较小、业务相对简单,选择分层架构更合适
  • 如果系统是大型企业级应用,需要集成多个遗留系统,SOA 的服务编排思想有价值
  • 如果团队缺乏经验丰富的架构师,应避免使用过于复杂的架构模式

总结

  • 分层架构是最常见的可扩展架构模式,也叫 N 层架构
  • C/S、B/S 架构按照用户交互划分,MVC、MVP 按照职责划分
  • 分层架构必须禁止跨层访问,保证边界清晰
  • SOA 是面向服务的架构,试图解决服务编排问题
  • ESB 是 SOA 的核心,但也是性能瓶颈所在
  • WS-* 标准过于复杂,学习和使用成本都很高
  • 分层架构适合简单业务,SOA 适合复杂企业系统
  • 架构设计应遵循"合适原则"和"简单原则"
  • 避免将微服务当作解决一切的银弹
  • 实际应用中可以根据需要组合使用多种架构模式

附录:Python 示例

以下示例演示分层架构的基本结构,展示各层职责分离的效果。

python
""" 分层架构示例:MVC 模式实现的学生信息管理 核心思想:各层职责分离,存储层变更不影响业务层 """ from abc import ABC, abstractmethod # ========== 存储层 ========== class StorageLayer: """存储层:负责数据的持久化""" def save(self, key, value): print(f"[存储层] 保存数据: {key} = {value}") def load(self, key): print(f"[存储层] 加载数据: {key}") return f"{key}_value" # 如果需要更换存储实现,只需替换这个类 class MongoStorage: """MongoDB 存储实现""" def save(self, key, value): print(f"[MongoDB] 存储文档: {key} = {value}") def load(self, key): print(f"[MongoDB] 查询文档: {key}") return f"mongo_{key}" # ========== 数据层 ========== class DataLayer: """数据层:负责数据访问逻辑""" def __init__(self, storage): self.storage = storage def create_user(self, username, info): print(f"[数据层] 创建用户记录") self.storage.save(f"user:{username}", info) def get_user(self, username): print(f"[数据层] 获取用户记录") return self.storage.load(f"user:{username}") # ========== 业务层 ========== class BusinessLayer: """业务层:负责业务逻辑处理""" def __init__(self, data_layer): self.data_layer = data_layer def register(self, username, password, email): # 业务逻辑验证 if len(password) < 6: print("[业务层] 密码长度不足") return False user_info = { "username": username, "email": email, "status": "active" } self.data_layer.create_user(username, user_info) print(f"[业务层] 用户 {username} 注册成功") return True # ========== 展示层 ========== class PresentationLayer: """展示层:负责用户界面交互""" def __init__(self, business_layer): self.business_layer = business_layer def show_register_page(self): print("[展示层] 显示注册页面") def handle_register_submit(self, username, password, email): print("[展示层] 提交注册请求") return self.business_layer.register(username, password, email) # 测试分层架构 if __name__ == "__main__": print("=== 使用 MySQL 存储 ===") mysql_storage = StorageLayer() data_layer = DataLayer(mysql_storage) business_layer = BusinessLayer(data_layer) presentation = PresentationLayer(business_layer) presentation.show_register_page() presentation.handle_register_submit("zhangsan", "password123", "zhangsan@example.com") print("\n=== 切换到 MongoDB 存储 ===") # 只需替换存储层,其他层无需修改 mongo_storage = MongoStorage() data_layer_mongo = DataLayer(mongo_storage) business_layer_mongo = BusinessLayer(data_layer_mongo) presentation_mongo = PresentationLayer(business_layer_mongo) presentation_mongo.handle_register_submit("lisi", "pass456", "lisi@example.com")

输出示例

=== 使用 MySQL 存储 === [展示层] 显示注册页面 [展示层] 提交注册请求 [业务层] 用户 zhangsan 注册成功 [数据层] 创建用户记录 [存储层] 保存数据: user:zhangsan = {'username': 'zhangsan', 'email': 'zhangsan@example.com', 'status': 'active'} === 切换到 MongoDB 存储 === [展示层] 提交注册请求 [业务层] 用户 lisi 注册成功 [数据层] 创建用户记录 [MongoDB] 存储文档: user:lisi = {'username': 'lisi', 'email': 'lisi@example.com', 'status': 'active'}

这个示例展示了分层架构的核心优势:当需要更换存储层实现(如从 MySQL 切换到 MongoDB)时,只需替换最底层的存储类,上层的业务逻辑和展示层完全无需改动。

参考资料

  • 软件架构基础