前言 技术朋友应该看过公司架构师画的各种架构图,五花八门,各种框框,还涉及很多概念,比如系统,子系统,模块,组件,框架等等。他们都有出现在架构师的架构图里,那这些名词都是什么含义呢?它们之间又存在什么样的关系呢?架构的本质又是什么呢? 这篇
作者:白色蜗牛 来源:蜗牛互联网
前言
技术朋友应该看过公司架构师画的各种架构图,五花八门,各种框框,还涉及很多概念,比如系统,子系统,模块,组件,框架等等。他们都有出现在架构师的架构图里,那这些名词都是什么含义呢?它们之间又存在什么样的关系呢?架构的本质又是什么呢?
这篇文章希望可以给到你答案!
系统与子系统
系统(System)这个词我们经常会听到,它在维基百科里的定义是这样的:
系统泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。
这个定义里有三个核心要点。
第一个是关联,必须是有关联的个体放一起才能成为系统。
第二个是规则,每个个体有各自的分工和协作方式,按照一定的规则运行。
第三个是能力,系统不是个体能力之和,而是产生新的能力,也就是 1+1>2 的效果。
比如计算机系统包括了 CPU、内存、磁盘和 IO。
IO 接收数据,内存放入运行中数据,CPU 进行计算,IO 输出计算结果,并且可以把相关信息比如日志持久化到磁盘中。
各个个体间互有关联,有着各自的分工和协作规则,并且完成了特定的计算,而这样子的计算任何一个个体是无法单独完成的。
至于子系统,往往是系统的颗粒度很大的时候,需要对这个系统拆解以方便分析。
因此,子系统(Subsystem)可以理解成更大系统中的一部分。
比如我们常用的微信可以认为是一个系统,而聊天,朋友圈就是子系统。其实如果视角上把朋友圈认为系统的话,也能找到它的子系统,比如动态、评论等子系统。
以下是系统和子系统的区别概要:
模块与组件
很多朋友实习的时候,师兄基本不会让你直接搞某个系统,而是给你某个模块或者某个组件练手。
那什么是模块,什么又是组件呢?
软件模块在维基百科的定义是这样的:
软件模块(Software Module)是一套一致而互相有紧密关连的软件组织。包含了程序和数据结构两个部分。现代软件开发往往利用模块作为合成的单位。模块的接口表达了由该模块提供的功能和调用它时所需的元素。模块是可能分开地被编写的单位,能允许广泛人员同时协作、编写及研究不同的模块。
从这个定义可以看出,模块有一套完整的功能,可以被分开编写。
软件组件在维基百科的定义是这样的:
软件组件(Software Component)定义为自包含的、可编程的、可重用的、与语言无关的软件单元,软件组件可以很容易被用于组装应用程序中。
从这个定义可以看出,组件更多强调的是重用,可组装。组件换一个说法,零件,会更容易理解,零件是一个物理概念,并且具备独立可替换的特点。
模块和组件都作为系统的单元,它们有什么差别呢?
可以从拆分系统的角度来思考这个问题。
从逻辑的角度来拆分系统,得到的单元就是模块。比如一个学生信息管理的网站系统,按逻辑(可以理解成功能)拆分,可分为登录注册模块,个人信息模块。
从物理角度来拆分系统,得到的单元就是组件。比如网站系统,按物理(可以理解成部署环境)拆分,可分为 Nginx,web 服务器 和 Mysql。
那划分模块主要是为了职责分离,而划分组件主要是为了单元复用。
以下是模块与组件的区别概要:
框架与架构
你在写某个模块或组件的时候,一定有用过框架吧!写注册登录模块你可能会用 Spring MVC,接入 Mysql 组件你可能会用 MyBatis。 Spring MVC 和 MyBatis 这些其实都是框架,那框架的定义是什么呢?
维基百科是这么定义的:
软件框架(Software Framework)通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。
从定义里,我们也能发现框架无非就两类,一类是组件规范,比如 MVC、J2EE,另一类是软件产品,比如 Spring MVC。
框架关注的是规范两个字,要么制定规范,要么实现规范。
那么架构又是指什么呢?
维基百科是这么定义的:
软件架构(Software Architecture)是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。软件架构会包括软件组件、组件之间的关系,组件特性以及组件间关系的特性。软件架构可以和建筑物的架构相比拟。软件架构是构建计算机软件,开发系统以及计划进行的基础,可以列出开发团队需要完成的任务。
分析下定义,我们找出几个关键词:整体结构,抽象描述和软件系统。
「整体结构」说明架构关注的是结构,至于产出什么样的结构,不同角度出发会有不一样的结果,比如 RUP 的 4+1 视图,就围绕着用例视图,从不同角度出发,得到了逻辑视图,实现视图,部署视图和过程视图,每个视图其实都可以认为是架构图。
「抽象描述」说明架构关注抽象的内容,它不会陷入细节,而是专注顶层设计。
「软件系统」说明了架构的适用场景,不是所有的软件开发都需要有专门的架构设计,需要到系统级别,同时也要根据规模视情况而定。
这些信息再综合一下,对于架构,我们可以得到一个更简洁的定义:软件架构是软件系统的顶层结构。
如下图所示:
首先,系统是一群关联个体组成,这些个体可以是子系统,模块,组件等,也就是架构需要明确系统中包含哪些个体。
其次,系统中的个体需要根据某种规则运作,也就是架构需要明确个体运作的规则。
最后,系统必须是最高层次的结构,从系统的视角出发,能覆盖的系统的全貌。
或许,现在你可以把框架和架构区分开了:
动手验证
# 看进程各线程的内存 / CPU 占用
top -H -p <pid>
# 某个端口被谁占着
lsof -i :8080
# 抓一次 HTTP 请求内容
sudo tcpdump -A -i any 'tcp port 8080' -c 50
延伸阅读:官方与权威资料
相关阅读(站内)
常见问题
Q:G1 GC 和 CMS 垃圾回收器有什么区别?
G1 把堆拆成多个 Region,用标记-整理避免内存碎片,目标是可预测的停顿时间;CMS 用标记-清除,回收快但会产生碎片。JDK 9 起 G1 成为默认收集器,JDK 14 移除 CMS。
Q:G1 的 Remembered Set 是干什么的?
Region 化之后跨 Region 的引用都要记账,Remembered Set 记录其他 Region 指向本 Region 的指针,回收某个 Region 时不用扫全堆,这是 G1 停顿可控的关键之一。
Q:怎么调优 G1 的停顿时间?
三步走:先把 -XX:MaxGCPauseMillis 设在合理区间(别贪低,太小会疯狂扩容堆)、再看 GC 日志里的 Mixed GC 频率定位大对象、用 -XX:InitiatingHeapOccupancyPercent 控制并发标记起手时机。
Q:为什么 Java 的 String 要设计成不可变?
不可变才能安全共享与缓存哈希值,也能安全地放进字符串常量池;一旦可变,其他线程持有引用时修改会破坏哈希表与缓存的一致性。
Q:Java 里 == 和 equals 的区别是什么?
== 比较引用地址,equals 比较对象内容。String、Integer 等包装类重写了 equals,自定义对象不重写 equals 时,equals 等价于 ==。
本文首发于 java4u.cn,转载请注明出处。
关注「蜗牛聊AI」,一起看懂技术变化背后的真正机会。

