架构篇一 架构的目的与准则

架构篇一 架构的目的与准则

Created
Jun 28, 2021 04:25 PM
Tags
架构
在古代的狼人传说中,只有用银质子弹(银弹)才能制服这些异常凶残的怪兽。在软件开发活动中,“银弹”特指人们渴望找到用于制服软件项目这头难缠的“怪兽”的“万能钥匙”。 软件开发过程包括了分析、设计、实现、测试、验证、部署、运维等多个环节。从IT技术的发展历程来看,先辈们在上述不同的环节中提出过很多在当时看来很先进的方法与理念。但是,这些 方法、理念在摩尔定律、业务创新、技术发展面前都被一一验证了以下观点:我们可以通过诸多方式去接近“银弹”,但很遗憾,软件活动中没有“银弹”。 布鲁克斯发表《人月神话》三十年后,又写了《设计原本》。他认为一个成功的软件项目的最重要因素就是设计,架构师、设计师需要在业务需求和IT技术中寻找到一个平衡点。个人觉得,对 这个平衡点的把握,就是架构设计中的取舍问题。而这种决策大部分是靠技术,但是一定程度上也依赖于架构师的“艺术”,技术可以依靠新工具、方法论、管理模式去提升,但是“艺术”无法量化 ,是一种权衡。 软件设计过程中,模块、对象、组件本质上是对一定规模软件在不同粒度和层次上的“拆分”方法论,软件架构是一种对软件的“组织”方法论。一分一合,其目的是为了软件研发过程中的成本、进 度、质量得到有效控制。但是,一个成功的软件设计是要适应并满足业务需求,同时不断“演化”的。设计需要根据业务的变化、技术的发展不断进行“演进”,这就决定了这是一个动态活动,出现 新问题,解决新问题,没有所谓的“一招鲜”。 以上只是针对设计领域的银弹讨论,放眼到软件全生命周期,银弹问题会更加突出。 小到一个软件开发团队,大到一个行业,没有银弹,但是“行业最佳实践”可以作为指路明灯。 —— 公号-Java大后端

目的

上世纪四十年代之前, 开发软件使用的"机器语言", 是直接使用0 1来进行编写指令与数据的, 四十年代之后, 出现了汇编语言, 用短小的单词如mov来表示指令, 大大加强了代码的可读性, 减少了编程的复杂度, 但是编写一个如加减乘除的实现依然很困难, 于是, 上世纪五十年代, 高级语言出现了, 如LISP, Cobol等, 这些就是现代常用编程语言的雏形。
可以看出, 编程语言的进化史, 就是化繁为简, 由复杂到简单。同理, 架构设计的目的, 也是一样的, 随着模块, 组件的越来越多, 系统的复杂性也会增加, 而架构设计的主要目的, 就是为了解决软件系统复杂度带来的问题。

准则

  • 通过熟悉和理解需求,识别系统复杂性所在的地方,然后针对这些复杂点进行架构设计。
  • 架构设计并不是要面面俱到,不需要每个架构都具备高性能、高可用、高扩展等特点,而是要识别出复杂点然后有针对性地解决问题。
  • 理解每个架构方案背后所需要解决的复杂点,然后才能对比自己的业务复杂点,参考复杂点相似的方案。
  • 如果系统的复杂度不是在性能这部分,TPS再高也没什么用。
  • 别人的架构是为了解决别人的问题,并不是所有软件的用户量都是某宝那么大。
  • 没有万能的软件,比如Docker只是为了解决资源重用和动态分配而设计的,如果系统复杂度根本不是在这方面,引入Docker没有什么意义。

复杂度的来源

高性能

软件系统中高性能带来的复杂度主要体现在两方面,一方面是单台计算机内部为了高性能带来的复杂度;另一方面是多台计算机集群为了高性能带来的复杂度。
单台计算机
进程
线程
多核处理器
多台计算机
任务分配: 每台机器都可以处理完整的业务任务,不同的任务分配到不同的机器上执行。
任务分解: 把原来大一统但复杂的业务系统,拆分成小而简单但需要多个系统配合的业务系统。优点: 简单的系统更加容易做到高性能, 可以针对单个任务进行扩展

高可用

定义: 系统无中断地执行其功能的能力,代表系统的可用性程度,是进行系统设计时的准则之一。
CAP定理: 存储高可用不可能同时满足“一致性、可用性、分区容错性”,最多满足其中两个。
高可用状态决策
独裁式: 当决策者本身故障时,整个系统就无法实现准确的状态决策
协商式: 如果两者的信息交换出现问题(比如主备连接中断),此时无法进行协商
民主式: 脑裂 (一般采用 "投票节点数必须超过系统总节点数一半" 规则来处理)
PS: 高可用是指正常提供服务的概率,主要和故障恢复时间有关;高可靠是指出问题的概率,主要和故障次数有关。

可扩展性

设计具备良好可扩展性的系统,有两个基本条件:正确预测变化、完美封装变化。
方案一: 将“变化”封装在一个“变化层”,将不变的部分封装在一个独立的“稳定层”。
1.系统需要拆分出变化层和稳定层
2.需要设计变化层和稳定层之间的接口
方案二: 提炼出一个“抽象层”和一个“实现层”。
这种方案典型的实践就是设计模式和规则引擎。

低成本

如果架构方案涉及几百上千甚至上万台服务器,成本就会变成一个非常重要的架 构设计考虑点。
比如:
  • 使用NoSQL数据库来解决关系型数据库高并发访问压力
  • ES解决关系型数据库like搜索低效的问题

安全

  • 功能安全: 例如,常见的XSS攻击、CSRF攻击、SQL注入、Windows漏洞、密码破解等
  • 架构安全: 防火墙攻击, DDoS攻击等

规模

规模带来复杂度的主要原因就是“量变引起质变”,当数量超过一定的阈值后,复杂度会发生质的变化。
  • 功能越来越多,导致系统复杂度指数级上升
  • .数据越来越多,系统复杂度发生质变