引子

互联网发展到今天,软件系统早就不是一个万行代码加上一台服务器这样的作坊玩具。BAT的服务器规模已经达到甚至超过百万级。传统企业向互联网的靠拢,势不可挡。

优秀的软件系统架构师就像大海航船舵手,指引着软件前进的方向,让企业在激烈的竞争中拔得头筹的同时,在企业内部尊享荣光。

只有兼具技术的深度和广度,并能克服人性弱点的资深IT从业者,才有机会成为一个优秀的架构师(高薪也是水到渠成的事情)。优秀的架构师是公不司的福音,反之就是公司的灾难。如果坏的种子已经埋下,那么"爆雷"是一定的,何时"爆"压反而不确定。

架构即人性,不切实际、追求繁杂、好大喜功的非理性的个人诉求,掺杂于甚至暗暗地主宰着整个理性的软件系统架构设计,这将置企业于危险境地!如果成为"人人喊打"的架构师, 岂不叹哉!

那么,怎么扎实地成为一名优秀的、人见人爱的架构师?

本文就先从软件架构最基本的概念和思维讲起。

软件架构:缘起

随着软件系统规模的增加,计算相关的算法和数据结构不再构成主要的设计问题;当系统由许多部分组成时,整个系统的组织,也就是所说的"软件架构",导致了一系列新的设计问题。

规模较大的软件系统会面临各种软件架构相关的问题,例如:
1、系统规模庞大,内部耦合严重,开发效率低。
2、系统耦合严重,牵一发动全身,后续修改和扩展困难。
3、系统逻辑复杂,容易出问题,出问题后很难排查和修复。

软件架构的出现有其历史必然性。

20世纪60年代第一次软件危机引出了"结构化编程",创造了"模块"概念;
20世纪80年代第二次软件危机引出了""面向对象编程",创造了"对象"概念;
到了20世纪90年代"软件架构"开始流行,创造了"组件"概念。

我们可以看到,"模块""对象""组件"本质上都是对达到一定规模的软件进行拆分,差别只是在于随着软件的复杂度不断增加,拆分的粒度越来越粗,拆分的角度越来越高。

《人月神话》中提到的IBM360大型系统,开发时间是1964年,那个时候结构化编程都还没有提出来,更不用说软件架构了。如果IBM360系统放不在20世纪90年代开发,不管是质量还是效率、成本,都会比1964年开始做要好得多,当然,这样我们可能就看不到《人月神话》了。

系统与子系统

系统泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。
关于系统定义的关键词如下。

(1)关联:系统是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个系统。例如,把一个发动机和一台PC放在一起不能称之为一个系统,把发动机、底盘、轮胎、车架组合起来才能成为一台汽车。

(2)规则:系统内的个体需要按照指定的规则运作,而不是单个个个体各自为政。规则规定了系统内个体分工和协作的方式。例如,汽车发动机负责产生动力,然后通过变速器和传动轴, 将动力输出到车轮上,从而驱动汽车前进。

(3)能力:系统能力与个体能力有本质的差别,系统能力不是是个体能力之和,而是产生了新的能力。例如,汽车能够载重前进,而发动机、变速器、传动轴、车轮本身都不具备这样的能力。

子系统的定义其实和系统的定义是一样的,只是观察的角度有有差异,一个系统可能是另外一个更大系统的子系统。

子系统也是由一群有关联的个体所组成的系统,多半是更大系统中的一部分。

模块与组件

【模块】 软件模块 (Module) 是一套一致且互相有紧密关联的软件组织,它包含程序和数据结构两部分。现代软件开发往往利用模块作为合成的单位。
模块的接口表达了由该模块提供的功能和调用它时所需的元素。
模块是可能分开被编写的单位,这使得它们可再用,并允许开发人员同时协作、编写及研究不同的模块。

【组件】 软件组件(Components)定义为自包含的、可编程的、可重用的、与语言无关的软件单元,软件组件可以很容易地被用于组装应用程序。

相信大部分人看完这两个定义还是一头雾水,看完也不知道至到底两者有什么区别。造成这种现象的根本原因是模块和组件都是系统的组成部分,只是从不同的角度拆分系统而已。

从逻辑的角度来拆分后得到的单元就是"模块";划分模块的主要目的是职责分离。

从物理的角度来拆分系统得到的单元就是"组件";划分组件的主要目的的是单元复用。

"组件"的英文单词 Component,对应中文的"零件"一词,"零件"更容易理解一些。
"零件"是一个物理的概念, 并且具备"独立且可替换"的特点。


组件化和模块化源于软件开发,现在越来越被更多地应用于UI设计当中。示意图如下。

在Angular 架构中,模块可以被认为是组件、指令、服务、管道、helpers 等的集合。
每个组件都可以使用在同一模块中声明的其他组件。要使用在其他模块中声明的组件,它们需要从该模块导出,并且该模块需要导入到我们需要该功能的模块中。
许多模块中的一个组合起来形成一个应用程序。

The module can be considered as a collection of components, directives, services, pipes, helpers, etc.
Each component can use other components, which are declared in the same module. To use components declared in other modules, they need to be exported from that module and the module needs to be imported into our module where we need that functionality.
One of many modules combines up to make an Application.

Arquitectura de Angular

框架与架构、结构

软件框架(Software Framework),通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范, 也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。

框架定义的关键部分是:

(1)框架是组件规范。例如,MVC就是一种最常见的开发规范,类似的还有MVP、MVVM、 J2EE等框架。
(2)框架提供基础功能的产品。例如,SpringMVC是MVC的开发框架,除了满足MVC 的规范,Spring提供了很多基础功能来帮助我们实现功能,包括注解(@Controller等)、Spring Security、SpringJPA等很多基础功能。

架构的定义如下(Software Architecture)
Software architecture refers to the fundamental structures of a software system, the discipline of
creating such structures, and the documentation of these structures.
简单翻译一下:软件架构是指软件系统的"基础结构",创造过这些基础结构的准则,以及对
这些结构的描述。

单纯从定义的角度来看,框架和架构的区别还是比较明显的,框架关注的是"规范", 架构关注的是"结构"。

框架的英文是Framework 。例如,SpringMVC 是"Web MVC Framework"。
架构的英文是Architecture。例如,Linux 操作系统的架构。

架构设计关键思维

架构设计的关键思维是判断和取舍,程序设计的关键思维是逻辑和实现。
很多程序员在转变为架构师后,很难一开始就意识到这个差异,还是按照写代码的方式去思考架构,这样会导致很多困惑。

架构设计原则

原则1: 合适原则

合适的架构优于业界领先的架构。
真正优秀的架构都是在企业当前人力、条件、业务等各种约束下设计出来的,能够合理地将资源整合在一起并发挥出最大功效,并且能够快速落地。

原则2:简单原则

简单的架构优于复杂的架构。
软件领域的复杂性体现在两方面:结构的复杂性、逻辑的复杂条性。

原则3:演化原则

架构需要随着业务的发展而不断演化。
对于建筑来说,永恒是主题;而对于软件来说,变化才是主是题。
软件架构设计类似于生物演化。

互联网软件架构模板

1、互联网标准技术架构模板

互联网软件架构模板如下图所示。

上面这张图基本上涵盖了互联网技术公司的大部分技术点,不同的公司只是在具体的技术实现上稍有差异,但不会跳出这个框架的范畴。

2、存储层

SQL:常用的有mysql,用于存储业务数据。互联网发展初期,各个业务一般都会独立运营mysql集群,但随着业务越来越多,mysql集群规模越来越大,那就有必要做成SQL平台。

NoSQL: 翻译为Not Only SQL,作为mysql的一种补充。Nosql一般本身就提供集群,且使用起来很方便,公司业务发展初期没有必要。一般Nosql集群的数量越来越多,那就有必要做成Nosql平台。

小文件:互联网中有很多小文件,比如商品图片,Facebook的图片。这类小文件具有数据小、数量巨大、访问大的特点。如果每个业务都去考虑小文件存储的话,就会出现重复造轮子现象,那就有必要做成小文件平台了。

大文件:互联网的大文件主要分为两类:一类是业务上的大数据,例如Youtube的视频、电影网站的电影;另一类是海量的日志数据,例如各种访问日志。实力雄厚的一些大公司会基于开源方案做成大数据平台。

3、开发层

开发框架:比如常见的Spring框架。
Web服务器:常见的有tomcat、jetty等。
容器:Docker可以极大降低运维成本,以及在实现动态扩容上非常方便。

4、服务层

配置中心:故名思义,配置中心就是集中管理各个系统的配置。
服务中心:解决跨系统依赖的配置和调度问题。比如有10个系统依赖A系统的x接口,此时A系统实现了一个y接口可以更好地支持x接口,那么如果直接更新10个系统依赖的配置将会很麻烦。
消息队列:支持系统解耦。

5、网络层

负载均衡:充当任务分配器的职责。
CDN:可以对一些常用文件进行就近缓存,来提高访问速度。
多机房:多机房的主要目的是备灾,当机房故障时可以快速地将业务切换到另外一个机房,这种切换操作允许一定时间的中断,比如10分钟,1个小时。
多中心:多中心的要求就更高了,要求同时对外提供服务,且业务能够自动在多中心之间切换,故障后不需人工干预或者很少的人工干预就能自动恢复。

6、用户层

用户管理:对各个系统的用户进行统一管理。
消息推送:根据不同途径分为短信、邮件、站内信、App推送。
存储云:实现是CDN+小文件存储。
图片云:实现也是CDN+小文件存储。为何不与存储云统一一套系统呢?这是因为图片业务的复杂性导致的。图片涉及的业务会更多,包括裁剪、压缩、美化、审核、水印等。

7、业务层

业务千差万别,各个互联网业务面对的主要问题是复杂度越来越高。此时就要用到拆和合的技术。拆即将一个大系统拆分为多个子系统,降低复杂度。当子系统越来越多,有可能就需要采用合的技术。

8、测试平台

测试平台的核心目的是提升测试效率。

9、运维平台

运维平台的核心职责分为四大块:配置、部署、监控、应急。

10、数据平台

数据平台的核心职责主要包含三部分:数据管理、数据分析和数据应用。

11、管理平台

管理平台的核心职责就是权限管理。

小结

  • NoSQL不是NoSQL,而是Not Only SQL,即NoSQL是SQL的衤不充。
  • NoSQL发展到一定规模后,一般都是走集群路线。
  • 在开源方案的基础上封装一个小文件存储平台并不是太难的事情。
  • 大数据存储和处理反而是最简单的,因为你别无选择,只能用这几个流行的开源方案。
  • 框架的选择,有一个总的原则:优选成熟的框架,避免盲目追逐新技术!
  • 互联网行业基本上都是"拿来主义",挑选一个流行的开源服务器即可
  • 配置中心主要为了解决系统数量增多后配置管理复杂和效率化低下的问题。
  • 服务中心目的是解决跨系统依赖的"配置"和"调度"问题。
  • 消息队列目的是为了实现跨系统异步通知。
  • DNS是最简单也是最常见的负载均衡方式,一般用来实现地理级别的均衡。
  • Nginx&LVS&F5用于同一地点内机器级别的负载均衡。
  • CDN是为了解决用户网络访问时的"最后一公里"效应,本质上是一种"以空间换时间"的加速策略。
  • 多机房设计最核心的设计因素就是如何处理时延带来的影响。
  • 多中心必须以多机房为前提,但从设计的角度来看,多中心相比多机房是本质上的飞越, 难度也高出一个等级。
  • 用户管理系统两个核心职责:单点登录和第三方授权登录。
  • 消息推送主要包含3个功能:设备管理(唯一标识、注册和注销)、连接管理和消息管理。
  • 除非BAT级别,一般不建议自己再重复造轮子了,直接买图片云和存储云服务可能是最快又最经济的方式。
  • 业务层降低复杂性最好的方式就是"拆",化整为零、分而治之,将整体复杂性分散到多个子业务或子系统里面去。
  • 运维平台核心的职责分为四大块:配置、部署、监控和应急。
  • 测试平台的核心目的是提升测试效率,从而提升产品质量,其设计关键就是自动化。
  • 数据平台的核心职责主要包括三部分:数据管理、数据分析和数据应用。
  • 管理平台的核心职责就是权限管理。

最后

技术成就梦想,坚持就能成功。

参考阅读

《从零开始学架构》

【《禅与计算机程序设计艺术》更多精华文章阅读】

  1. 程序员修炼之道:务以己任,实则明心——通向务实的最高境界

  2. 程序员架构修炼之道:如何设计“易理解”的系统架构?

  3. 程序员架构修炼之道:如何设计出可持续演进的系统架构?

  4. 成为优秀架构师必备技能:怎样才能画出让所有人赞不绝口的系统架构图?秘诀是什么?快来打开这篇文章看看吧!

  5. 代码阅读方法与最佳实践

  6. 软件架构设计的核心:抽象与模型、“战略编程”

  7. 编程语言:类型系统的本质

  8. 软件架构的本质

  9. 浅谈工程师成长——关于成长的三个小故事

  10. 快看软件架构风格总结: 各种历史和现代软件架构风格的快速总结

  11. 怎样才算是好程序员?关于好程序员与好代码的杂谈

  12. 怎样在你的团队做 Code Review ?

  13. 关于软件架构设计的核心思想与标准 ( IEEE 1471 2000 )

  14. 关系代数(Relational Algebra)——极简教程

程序员架构修炼之道:软件架构基本概念和思维相关推荐

  1. 程序员架构修炼之道:如何设计“易理解”的系统架构?

    前言 尽管"可靠性"有时被视为"可用性"的同义词,但这一属性实际上意味着系统的所有关键设计的保证:可用性.持久性和安全不变量等. 我们构建易于理解的系统的主要指 ...

  2. 《程序员的修炼之道——从小工到专家》读书笔记

    概览 最近读了<程序员的修炼之道--从小工到专家>这本书,感觉这本书又是属于开发进阶的必读的一本著作,而且我觉得一遍甚至还只是入门,这是一本值得都第二遍的书.再次推荐给大家,没看过的都去看 ...

  3. 程序员的修炼之道,原文:程序员如何赚大钱?

    (本文共分三部分,现在打开的是<第一部分>,欢迎继续阅读<第二部分>和<第三部分>) 1 引子 都说海阔凭鱼跃,又有多少鱼能跃出大海?都说天高任鸟飞,但真正能一飞冲 ...

  4. 程序员的修炼之道:从小工到专家(一)

    阅读进度: 第一章 注重实效的哲学(1~6) 第二章 注重实效的途径(7~8) 第一次阅读这本书,说句老实话,由于水平有限,编 0程的经验又不足,觉得读起来有点晦涩,不太习惯这种文章的描述风格,没有读 ...

  5. 程序员的修炼之道——从小工到专家

    1.在所有的弱点中,最大的弱点就是害怕弱点暴露. 负责任的工作,注重实效性. 2.提供各种选择,不要找蹩脚的接口. 面对问题的时候,要想着如何解决问题,而不是找理由逃避. 3.软件腐烂(熵),不容忍破 ...

  6. 设计模式的艺术——软件开发人员内功修炼之道 重磅来袭

    今天(2012年12月17日),拿到了清华大学出版社给我寄的<设计模式的艺术--软件开发人员内功修炼之道>样书,这本近400页的书凝聚了过去多年我对设计模式的实战经验和教学精华,感谢清华大 ...

  7. 《设计模式的艺术——软件开发人员内功修炼之道》重磅来袭!

    今天(2012年12月17日),拿到了清华大学出版社给我寄的<设计模式的艺术--软件开发人员内功修炼之道>样书,这本近400页的书凝聚了过去多年我对设计模式的实战经验和教学精华,感谢清华大 ...

  8. 《高效程序员的修炼》读后感

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 首先非常感谢陆经理的赠书,如有想购买的同学,可到京东购买,地址:http://item.jd.com ...

  9. 程序员不爱读书,但这很不明智——想看就看《高效能程序员的修炼》

    英文原文:http://www.codinghorror.com/blog/2008/04/programmers-dont-read-books----but-you-should.html 作者: ...

最新文章

  1. chrome出现adobe flash playe 不是最新版本
  2. 计算机网络 实验六 静态路由配置,《计算机网络》实六 静态路由配置 实验报告.doc...
  3. python3 redis操作 错误 cannot import name 'StrictRedis' from 'redis'
  4. python 字符串前面加u,r,b,f的含义
  5. 互联网日报 | 3月7日 星期日 | 《你好,李焕英》成中国影史票房亚军;丰巢新增智能存包柜业务;特斯拉推出内部社交平台...
  6. Fedora 11的新特征和简易安置教程
  7. 2PC 二阶段提交协议与3PC
  8. php开发手册pdf版,TP5.0手册下载
  9. Java爬虫高级教程-动力节点
  10. 基于 DSP+FPGA 的排爆机器人控制系统设计与实现
  11. Unity Hub和Unity安装教程
  12. win10 linux 傲腾,Win10 版本 2004 导致英特尔傲腾内存出问题,千万不要强制升级
  13. chrome浏览器 Adobe Flash 版本太旧 无法播放视频解决办法
  14. 下载官方 Win11、Win10 镜像 ISO 的方法
  15. 揭晓丨易知微吉祥物WEI WEI IP形象设计大赛获奖作品出炉
  16. 计算机无法访问iTunes,无法连接到iTunes Store解决方法介绍
  17. ACCV 2020 Mutual Guidance
  18. 《Learning Scrapy》(中文版)第10章 理解Scrapy的性能
  19. 利用Python进行曲线拟合
  20. 数据查询和业务流分开_内销业务管理解决方案

热门文章

  1. java基础之—TreeSet集合学习笔记
  2. signature=b8b7708fbcb2dc05aab2f56dfec583f5,ゲームアップデート内容
  3. 打开命令行窗口的方式
  4. BPDU Gard / BPDU Filter / Root Guard
  5. 如何做成功的项目经理
  6. 升级Python2.7导致使用pip等命令安装模块失败
  7. vlc多媒体播放器VLC Media Player 3.0.7.1中文版
  8. SELECT list is not in GROUP BY clause and contains nonaggregated column
  9. ios使用gpx_使用JavaScript处理GPX轨道
  10. ijk播放器缓冲机制