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

目录

前言
可扩展的基本思想
拆分的三种思路
案例分析:TCP/IP协议栈
案例分析:学生信息管理系统
可扩展方式
可扩展架构分类
总结
附录:Python 示例
参考资料

前言

软件系统与硬件和建筑系统最大的差异在于软件是可扩展的。一颗 CPU 生产出来后不会返回工厂加工以增加新功能;金字塔矗立千年,但其结构与建成时并无两样。相比之下,软件系统完全相反——如果一个软件系统开发出来后再也没有任何更新,反而说明这套系统没有发展、没有生命力。真正有生命力的软件系统,都是在不断迭代和发展的。

今天我们进入架构可扩展模式的学习。这部分内容包括分层架构、SOA 架构、微服务和微内核等。

软件系统的这种天生可扩展特性,既是魅力所在,又是难点所在。魅力体现在我们可以通过修改和扩展,让软件系统具备更多的功能和特性。难点体现在如何以最小的代价去扩展系统,因为很多情况下牵一发动全身,扩展时可能出现到处都要改,到处都要推倒重来的情况。

可扩展的基本思想

幸运的是,可扩展性架构的设计方法虽然繁多,但万变不离其宗,所有可扩展性架构设计背后的基本思想都可以总结为一个字:

拆,就是将原本大一统的系统拆分成多个规模小的部分,扩展时只修改其中一部分即可,无须整个系统到处都改,通过这种方式来减少改动范围,降低改动风险。

说起来好像挺简单,毕竟"拆"我们见得太多了。但面对软件系统,拆就没那么简单了,因为我们并不是要摧毁一个软件系统,而是要通过拆让软件系统变得更加优美。形象地说,软件系统中的"拆"是建设性的,因此难度要高得多。

拆分的三种思路

按照不同的思路来拆分软件系统,就会得到不同的架构。常见的拆分思路有如下三种:

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

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

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

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

案例分析:TCP/IP协议栈

以 TCP/IP 协议栈为例:

  • 流程 对应 TCP/IP 四层模型,因为 TCP/IP 网络通信流程是:应用层 → 传输层 → 网络层 → 物理+数据链路层,不管最上层的应用层是什么,这个流程都不会变。

  • 服务 对应应用层的 HTTP、FTP、SMTP 等服务,HTTP 提供 Web 服务,FTP 提供文件服务,SMTP 提供邮件服务。

  • 功能 每个服务都会提供相应的功能。例如,HTTP 服务提供 GET、POST 功能,FTP 提供上传下载功能,SMTP 提供邮件发送和收取功能。

案例分析:学生信息管理系统

以一个简单的学生信息管理系统为例:

面向流程拆分:展示层 → 业务层 → 数据层 → 存储层

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

面向服务拆分:将系统拆分为注册、登录、信息管理、安全设置等服务。

面向功能拆分:每个服务都可以拆分为更多细粒度的功能。例如注册服务可拆分为手机号注册、身份证注册、学生邮箱注册三个功能。

可扩展方式

不同的拆分方式,本质上决定了系统的扩展方式。当我们谈可扩展性时,很多同学都会有一个疑惑:就算是不拆分系统,只要在设计和写代码时做好了,同样不会出现到处改的问题啊?

在一个理想的环境,团队都是高手,每个程序员都很厉害,那确实不拆分也没有问题。但现实却是:团队有菜鸟程序员,到底是改 A 处还是改 B 处,完全取决于他觉得哪里容易改;有的程序员比较粗心;有的程序员某天精神状态不太好……所有这些问题都可能出现,这时候你就会发现,合理的拆分,能够强制保证即使程序员出错,出错的范围也不会太广,影响也不会太大。

面向流程拆分的优势:扩展时大部分情况只需要修改某一层,少部分情况可能修改关联的两层,不会出现所有层都同时要修改。

面向服务拆分的优势:对某个服务扩展或者要增加新服务时,只需要扩展相关服务即可,无须修改所有的服务。

面向功能拆分的优势:对某个功能扩展或者要增加新功能时,只需要扩展相关功能即可。

可扩展架构分类

不同的拆分方式,将得到不同的系统架构:

  • 面向流程拆分:分层架构
  • 面向服务拆分:SOA、微服务
  • 面向功能拆分:微内核架构

这几个系统架构并不是非此即彼的,而是可以在系统架构设计中进行组合使用。例如,整体系统采用微服务架构,拆分为注册、登录、信息管理、安全服务等独立子系统;其中的注册服务子系统本身采用分层架构;登录服务子系统采用微内核架构。

总结

  • 软件系统的可扩展性是其与硬件、建筑系统的根本区别
  • 可扩展架构的核心思想是"拆"——将大一统系统拆分为小部分
  • 三种拆分思路:面向流程、面向服务、面向功能
  • 范围大小:流程 > 服务 > 功能
  • 合理拆分能强制限制出错范围,降低改动风险
  • 分层架构基于面向流程拆分
  • SOA和微服务基于面向服务拆分
  • 微内核架构基于面向功能拆分
  • 不同架构模式可以组合使用
  • 架构设计没有标准答案,需要根据实际情况选择

附录:Python 示例

以下示例演示面向服务拆分的简单实现,展示如何通过拆分降低改动范围。

python
""" 面向服务拆分示例:学生信息管理系统 核心思想:将系统拆分为独立服务,扩展时只需修改相关服务 """ # 定义各个服务的接口 class RegisterService: """注册服务""" def register(self, username, password): print(f"用户 {username} 注册成功") return {"status": "success", "service": "register"} def add_registration_method(self, method_name): """扩展注册方式(如增加学号注册)""" print(f"新增注册方式:{method_name}") # 只需修改本服务,无须修改登录服务、信息管理服务等 setattr(self, f"register_by_{method_name}", lambda u, p: print(f"使用{method_name}注册用户 {u}")) class LoginService: """登录服务""" def login(self, username, password): print(f"用户 {username} 登录成功") return {"status": "success", "service": "login"} class InfoService: """信息管理服务""" def query_info(self, username): print(f"查询用户 {username} 的信息") return {"username": username, "service": "info"} # 服务组合类 class StudentManagementSystem: def __init__(self): self.register_service = RegisterService() self.login_service = LoginService() self.info_service = InfoService() def register(self, username, password): return self.register_service.register(username, password) def login(self, username, password): return self.login_service.login(username, password) # 测试:演示扩展时的影响范围 if __name__ == "__main__": system = StudentManagementSystem() print("=== 正常功能 ===") system.register("zhangsan", "password123") system.login("zhangsan", "password123") print("\n=== 扩展注册服务:增加学号注册方式 ===") # 扩展注册服务时,只需要修改 RegisterService # LoginService 和 InfoService 完全不受影响 system.register_service.add_registration_method("student_id") print("\n=== 调用新增的注册方式 ===") if hasattr(system.register_service, 'register_by_student_id'): system.register_service.register_by_student_id("2024001", "pass456")

输出示例

=== 正常功能 === 用户 zhangsan 注册成功 用户 zhangsan 登录成功 === 扩展注册服务:增加学号注册方式 === 新增注册方式:student_id === 调用新增的注册方式 === 使用student_id注册用户 2024001

这个示例展示了面向服务拆分的核心优势:当需要增加新功能时,只需要修改对应的服务类,其他服务完全不受影响,从而限制了改动的范围。

参考资料

  • 软件架构基础