架构入门与架构师职责

这篇文章只是我对于架构认识的一些观点,如果您不认同我的观点或想和我讨论的话,十分欢迎评论指教。希望本文能帮助您在架构设计的路上多一点思考。
本篇文章主要讲架构的一些定义和架构师的职责,最后还有一些如何设计架构的原则和观点。在开始正文前我先抛出3个问题:
  1. 什么是架构? 框架、架构、模块、组件的区别与联系是什么?
  2. 架构师的定义是什么? 他到底是做什么的? 什么是称职的架构师?
  3. 架构师如何设计出高性能、高扩展性、高可用性的架构?
1. 架构 1.1 什么是架构 先看看wiki百科给的架构的定义:
软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口来实现。
软件架构本质是为了满足客户需求而需要的设计方案,它描述模块、组件以及它们之间的关系。其实wiki百科中给的解释还把软件架构和建筑物的架构作类比,但我认为它们之间是有很大的不同的。
软件拥有一个很大的特点,就是易变性,他所依赖的需求不稳定。所以要求架构师所创造的东西具有足够的灵活性,并且能够根据用户的需求进行演化。
1.2 那框架和架构到底是什么关系呢? 模块和组件是什么关系呢?
框架是: 为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。
  • 可以举例出: MVC框架,springMVC框架就是其中的一个特别实现。它定义了一组软件规范,并且以注解的形式提供了该框架的基础功能。
模块和组件的关系其实只是角度上的差别。模块设计的作用是职责分离; 组件设计的作用是单元复用。
  • 从软件逻辑上看,一个大的学生管理系统可以划分为学生登入管理系统、学生信息管理系统等;
  • 从物理角度看,又可以看成数据库组件、ngix组件等。
1.3 架构要素和架构设计套路 设计一个架构要注意什么方面呢(可能不完善还请见谅):
  1. 职责明确的模块和组件(高内聚和低耦合的体现)
  2. 组件间明确的关联关系(一对多?一对一?多对多?)
  3. 详细清晰的约束和指导原则(例如:单一原则、里式替换原则、开闭原则以及依据业务自定义的其他原则等)
【架构入门与架构师职责】以下是架构师的一般性设计套路,关于架构师定义和职责相关的在后文会提及:
  • 定义问题->确定架构->提出方案->落地。
一个架构设计最难得地方就是定义问题的部分: 什么是最需要注意? 什么是系统的瓶颈所在? 在这一步要看清主次矛盾,但也要注意主次矛盾是会互相变换的(从这点看,架构师还需要点哲学的思想呢哈哈)。
例如当业务比较小时,特别是初创公司,可能成本是首要矛盾,而对于大型公司、或业务从小发展到大,成本可能不再是首要矛盾,TPS、QPS这些性能方面的东西可能是首要注意点。
而对于定位问题,要有打破砂锅问到底精神(5why分析法),如下图所示,最初知识想要提升用户体验,但随着不断的深入研究探索,发现了更多的需要注定的点,这时架构师可能就得利用自己经验来判断出哪个才是首要矛盾。
架构入门与架构师职责
文章图片

架构设计如此复杂且吃经验,那有没有一些架构设计的原则指导呢?
1.4 架构设计原则 虽然架构设计总是伴随着需求的不确定性、技术选型的复杂性,但架构设计还是可以总结出三个原则,分别是: 合适原则、简单原则、演化原则。
1.4.1 合适原则
看业务是否需要,是否必要、是否合适。很多技术人员成为架构师总是会有一些技术上的渴求,想要设计出最牛的最好的架构,但往往这样的架构要么设计不出来,要么复杂度太高,实现成本太高。
架构设计是服务于业务的。架构设计的本质其实是取舍(这就需要架构师拥有足够的技术储备),架构设计没有银弹,只有针对不同的业务情况进行设计才能设计出好的架构。
举一个学生管理系统的例子: 作为学生管理系统,进入流量的大小大致是有数而且不大的,不需要进行高性能的设计,高可扩展性也是不太需要的,但如果数据库宕机了甚至机器坏了,学生数据就得管理人员一条一条的输入,这是很麻烦的,所以需要足够的可用性。
1.4.2 简单原则
能用简单的技术满足需要就不要给自己的团队增加工作量。在合适原则的基础上尽量选择团队成员最熟悉的,技术上实现最简单的。越复杂的技术对研发人员的要求就越高,维护的成本也会增加。
1.4.3 演化原则
不要试图一开始进行"长远考虑",过度的提前设计只会把整个团队拖入泥潭。
要做好不断迭代优化的准备,在开发的层面上可以采用敏捷开发的思想(敏捷开发也说明过度设计是弊大于利的)。
虽然说架构师所要设计的业务需求是不断变化的(特别是当今的互联网行业),但要想捕捉到未来的需求是十分难的,首先是确定未来可能的需求变化,接着针对这种变化进行针对性设计。可是谁也不能保证架构师所预计的需求变化真的会发生。如果不发生,轻则浪费了研发资源,重则对之后的开发还有负面影响。
架构师要审慎的进行"面向未来"设计,毕竟没有一种架构设计是银弹,不要太深入到一种架构设计中去,保留足够的变更空间。
2. 架构师 软件架构的功能是控制软件的复杂度。软件架构师的工作就是控制软件的复杂度。
软件的复杂度在于一台机器和不同机器间。例如: 同一台机器内有同步/异步的选型; 不同的机器间有状态机的选型。
自从软件出生以来,软件开发和软件的复杂度一直如影随行。从最早的机器语言,到中低级编程语言,到软件工程、面向对象出现,都在处理软件复杂的的问题。但是软件复杂度的解决方案也没有银弹。之后软件规模越来越大,甚至出现了分布式的软件系统,对于大型软件,架构设计越来越有必要。
2.1 架构师职责 让我看看看wiki上的定义:
是在信息系统研发中,负责依据需求来确定主要的技术选择、设计系统的主体框架结构,并负责搭建实施的人。[1] 他们(与系统分析师共同)确立系统的主体架构和实现方向,并负责指导软件工程师等开发人员的编码开发工作。
让我抽取出一些核心的概念: 技术选择、负责搭建实施、指导软件工程师。
在目前的业界情况,其实还可以用五个字来概括软件架构师: 人、财、物、是、事。其实软件架构师管理的不仅仅是软件,还有管理团队。敏捷开发和<<微服务设计>>都说明:
在最理想的情况下,架构师应该和开发人员一起编码,如果架构师实在很忙那也应该和开发人员一起工作。
架构师本质工作是管理人员,或者就是管理开发人员。所以系统架构的设计也需要和团队组织结构具有足够的一致性。技术选型也是如此。
不仅不能成为所谓的"ppt架构师",也不能成为架构设计出来后就甩手而去的"架构师"。架构师在团队开发的过程中要保证团队具有良好的开发节奏(开发、测试、部署,做好增量开发部署的准备),把握好开发进度(立会制度就很好)。此处额外说明下: 立会就是站着开会的意思,在立会上不要深入讨论开发细节,主要目的是了解开发进度,最好时间控制在10~15m之间。同时也能培养出"代码集体所有制"的氛围,避免单人负责导致思维盲点。
同时,拥抱变化而不要畏惧变化。
2.2 架构设计浅谈 2.2.1 CAP原理
CAP三个大写字符分别是: Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容忍性)。
C和A比较好理解,那P是什么意思呢? 我的理解是: 忍的是"同步时间差"。在多实例下,实例间的状态同步需要一定的时间,所以多实例下P必然要成立。
更多CAP的相关信息可以看这里: https://zhuanlan.zhihu.com/p/20399316
2.2.2 高性能、高可用、高扩展相关
高性能和高可用本质上都是通过加机器来实现。高性能目标的加机器叫扩展,高可用的加机器叫冗余。
高性能是软件架构最复杂的地方。软件架构的复杂性在高性能上可以体现在两个方面:
  1. 单台计算机内部复杂度: 线程\进程、阻塞\非阻塞等。
  2. 多台机器之间的复杂交互: 异步\同步、消息队列、请求/响应、事件/订阅等。
高可用加机器是为了扩展性能,往往伴随着状态决策机制。状态决策机制有三种:
  1. 独裁式。一台机器进行状态决策,可用性不够。
  2. 协商式。主备或主从形式。
  3. 民主式。zookeeper中的paxos变体算法就是民主式。民主式会有一个"脑裂"的问题(因为通信失败导致有多个决策主体发布状态信息),所以往往要求超过一半的投票次数满足了才能通过对应的"提议"。
高可用分为计算高可用、存储高可用、应用高可用。常见的高可用方案有加机器且负载均衡路由、冗余备份、超时设置、异步调用(解耦)、服务降级保护、监控告警、灰度发布和回滚机制等。
高扩展性的设计在飞快变化的需求面前往往是必不可少的。设计高可用的架构首先在于识别业务可能会发生的变化。识别出变化点后,套用高耦合低内聚的原则、单一原则、依赖倒置原则等,模块和模块间的通信也设计成尽量稳定的或易于修改的(客户端和服务端公用一套公共库是一件很糟糕的事情)。
设计高扩展性架构时同时要记住不要过度设计。大服务拆分成小服务比小服务设计出来后不合适于业务要重新开发成本要低多了。
关于高扩展性的更多可以参考这里: https://www.cnblogs.com/dimmacro/p/4568905.html
2.2.3 安全、成本
安全也是架构的一个重要方面,架构安全可以大致分为两个方面:
  1. 功能安全
  2. 架构安全
功能安全像是防小偷,大致可能的威胁来源有:XSS漏洞、CSRF漏洞、SQL漏洞、越权漏洞等。
架构安全像是防强盗,往往类型像是给架构一记重重拳击,动辄几十上百TB的流量冲击,击穿缓存、击垮数据库等。
成本对于架构设计来说,相当于一个约束。在设计高可用、高扩展等"高"架构时,成本往往是对这些追求的限制,要想突破限制只能通过创新来实现既降低成本又"高"的架构。
参考资料
  1. 高可用: https://zhuanlan.zhihu.com/p/28059511
  2. 高性能: https://my.oschina.net/jayqqaa12/blog/3161787
  3. https://www.cnblogs.com/dimmacro/p/4568905.html
  4. <<微服务设计>>
  5. <<高效程序员的45个习惯>>
  6. 极客时间: 从0开始学架构

    推荐阅读