最近笔者在密谋一个开源项目,在脑暴阶段,一直在考量基于项目属性而落地的软件架构选型,也想趁这个时期,结合个人经验和课程学习,做一些知识输出。
概念
参考维基百科中的定义:软件架构指软件系统的“基础结构”,创造这些基础结构的准则,以及对这些结构的描述。
我们看一个常见的WEB软件架构图:
软件架构图
笔者理解软件架构就是一个系统的草图,草图中描述直接构成系统的各个抽象组件,描述各个组件之间的通讯,而在实现阶段,草图中的各个抽象组件会被细化为实际的组件,比如具体某个类或者对象,它可以用于指导软件系统各个方面的设计。
而我们在搬砖的架构设计过程,是这样的:
搬砖A:“头,我们要造什么?”;(做什么系统?)
包工头:“梦商城”;(XXX系统,比如微博系统)
搬砖A:“图纸画出来了嘛?”;(架构是怎么设计的?)
包工头:“一楼主要以女性消费为主体、二楼以大众娱乐为主体、三楼以美食为主体”;(相当于微博系统中的各个子系统,比如评论子系统、动态子系统、消息子系统)
搬砖A:“头,说人话”;
包工头:“一楼有卖衣服、化妆品的,二楼有唱歌、看电影的,三楼有吃的”;(【模块】按照逻辑区分,比如存储数据模块、搜索模块、文章模块)
搬砖A:“有没有很知名的店啊?”;
包工头:“有的,一楼有耐克、优衣库...、二楼有红歌会、万达影院....、三楼有海底捞、星巴克.....”;(【组件】按照物理区分,存储数据模块对应Mysql、搜索模块对应ElasticSearch)
搬砖A:“对了,头,商城大门有啥施工规范不?有没有啥新套路用得上?”;(有框架的可以用吗?)
包工头猛吸了一口烟,把烟头扔在地上,用皮鞋左右撵了两下,缓缓从嘴里崩出四个字:“老样子吧”。(spring全家桶甩起来)
当然其实很常见的例子是,大多数的项目会采用公司自己沉淀的底层,在换换包装。
历史探索
笔者各种采集软件开发进化的历史信息,带大家探索一下软件架构出现的历史背景。
软件开发进化的历史机器语言(1940 年之前)
最早的软件开发使用的是“机器语言”,直接使用二进制码 0 和 1 来表示机器可以识别的指令和数据。
那时候的代码是这样的:
101100000000000000000011
000001010000000000110000
001011010000000000000101
笔者听闻这样的代码模式时,是直接懵逼的,我是谁?我在哪?我在看什么鬼?这样的代码如果出现错误,我该怎么办?非常敬佩当年的程序大神。
问号脸汇编语言(20 世纪 40 年代)
汇编语言的出现主要是为了解决机器语言编写、阅读、修改复杂的问题。汇编语言又叫“符号语言”,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。
汇编语言实现简单的加法运算代码是这样的:
.section .data
a: .int 10
b: .int 20
format: .asciz "%d\n"
.section .text
.global _start
_start:
movl a, %edx
addl b, %edx
pushl %edx
pushl $format
call printf
movl $0, (%esp)
call exit
对于现代程序员来讲,这种语法还是非常复杂的,代码量也非常之大,而且当时还有另外一个更复杂的问题:不同 CPU 的汇编指令和结构是不同的,也就是说不通CPU下同样的代码要多写一遍。
高级语言(20 世纪 50 年代)
有痛苦就继续反抗,为了解决汇编语言的问题,计算机前辈们从 20 世纪 50 年代开始又设计了多个高级语言,最初的高级语言有下面几个,并且这些语言至今还在特定的领域继续使用。
- Fortran:1955 年,名称取自”FORmula TRANslator”,即公式翻译器,由约翰·巴科斯(John Backus)等人发明。
- LISP:1958 年,名称取自”LISt Processor”,即枚举处理器,由约翰·麦卡锡(John McCarthy)等人发明。
- Cobol:1959 年,名称取自”Common Business Oriented Language”,即通用商业导向语言,由葛丽丝·霍普(Grace Hopper)发明。
为何称为高级语言呢?还是以实现一个简单的加法运算代码为例:
(+ 4 6)
对比汇编语言,瞬间感觉这样的语法高大上,对程序猿来讲是一次大大的解放。通过编译程序的处理,高级语言可以被编译为适合不同 CPU 指令的机器语言。程序员只要写一次程序,就可以在多个不同的机器上编译运行,也彻底解决了汇编语言一码多写的弊端。
结构化程序设计(20 世纪 60 年代~20 世纪 70 年代)
高级语言的出现,解放了程序员,但好景不长,随着软件的规模和复杂性的增加,典型的表现:
- 软件质量低下.
- 项目无法如期完成.
- 项目严重超出预计支出等。
这就是传说中的第一次软件危机,而危机中各方人士发布解决方法,其中艾兹赫尔·戴克斯特拉(Edsger Dijkstra)于 1968 年发表了著名的《GOTO 有害论》论文,引起了长达数年的论战,并由此产生了结构化程序设计方法。
结构化程序设计本质上还是一种面向过程的设计思想,但通过“自顶向下、逐步细化、模块化”的方法,将软件的复杂度控制在一定范围内,从而从整体上降低了软件开发的复杂度。结构化程序方法成为了 20 世纪 70 年代软件开发的潮流。
面向对象(20 世纪 80 年代)
结构化编程的风靡在一定程度上缓解了软件危机,然而随着硬件的快速发展,业务需求越来越复杂,以及编程应用领域越来越广泛,引发了第二次软件危机。
第二次软件危机的根本原因还是在于软件生产力远远跟不上硬件和业务的发展,主要体现在软件“扩展”变得非常复杂。
在这种背景下,面向对象的思想开始流行起来,主要得益于 C++ 的功劳,后来的 Java、C# 把面向对象推向了新的高峰。到现在为止,面向对象已经成为了主流的开发思想。
软件架构-组件化程序设计(20 世纪 90 年代)
在一些大公司中,随着软件规模越发的庞大,软件系统在次面临难题:
- 系统规模庞大,内部耦合严重,开发效率低.
- 系统耦合严重,牵一发动全身,后续修改和扩展困难.
- 系统逻辑复杂,容易出问题,出问题后很难排查和修复.
而基于此,引发了“软件架构”的潮流,创造了“组件”概念。
组件化是基于可重用的目的,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的组件,主要目的就是减少耦合。一个独立的组件可以是一个软件包、web服务、web资源或者是封装了一些函数的模块。这样,独立出来的组件可以单独维护和升级而不会影响到其他的组件。
软件架构-面向服务SOA(2000年代)
而随着软件开发成本的增加,提升软件的开发效率、可重用性和可维护性等难题也迫在眉睫。程序猿们很快把一些生活中的例子作为参考去做设计,比如生活中,人们需要实现某种需求时,通常是去看市场是否有这种工具在售,而不会去关心这个东西是怎么做成的,而把这个逻辑套用在程序中,如果把如用户管理模块作为一个服务去对外提供,这样可以预想到,会大大提高软件的开发效率、可重用性和可维护性。
当然面向服务架构其实在2O世纪9O年代中期,Gartner( 高德纳,又译顾能公司,全球最具权威的IT研究与顾问咨询公司)就提出的面向服务架构的概念。
面向服务架构,从语义上说,它与面向过程、面向对象、面向组件一样,是一种软件组建及开发的方式。与以往的软件开发、架构模式一样,SOA只是一种体系、一种思想,而不是某种具体的软件产品。
软件架构-微服务(21 世纪 10年代)
微服务是互联网高速发展,敏捷、精益、持续交付方法论的深入人心,虚拟化技术与DevOps文化的快速发展以及传统单块架构无法适应快速变化等多重因素的推动下所诞生的产物。
微服务架构(MicroService)是一种服务化架构风格,通过将功能分散到各个离散的服务中以实现对解决方案的解耦。微服务架构强调的第一个重点就是业务系统需要彻底的组件化和服务化。
为什么有了SOA架构为什么会出现微服务架构呢?
SOA架构有局限性,就是所有的接口都需要走ESB,如果不同的编程语言开发子系统,而这个编程语言对于某种RCP协议支持是最友好的,而ESB规则限定其只能使用ESB的规定协议。而微服务的去中心化的思想,不在使用ESB作为通信的桥梁,服务、系统之间可以相互访问,也可以针对不同服务制定对应的技术方案。
小结
今天主要是将软件架构的概念和发展历史进行一些概述。
- 软件架构指软件系统的“基础结构”,创造这些基础结构的准则,以及对这些结构的描述。
- 20 世纪 60 年代第一次软件危机引出了“结构化编程”,创造了“模块”概念;20 世纪 80 年代第二次软件危机引出了“面向对象编程”,创造了“对象”概念;到了 20 世纪 90 年代“软件架构”开始流行,创造了“组件”概念,2000年代“面向服务”开始流行,创造了“服务”概念,21 世纪 10年代互联网高速发展诞生微服务。
- “模块”、“对象”、“组件”、“服务”本质上都是对达到一定规模的软件进行拆分,差别只是在于随着软件的复杂度不断增加,拆分的粒度越来越细,拆分的层次越来越高。
思考问题
- 你理解的软件架构是什么?在系统实施过程中充当什么样的作用?
- 软件开发进化中,还有哪些重大事件发生过或可能发生?
欢迎你把答案写到留言区,和我一起讨论。
网友评论