如何成为SM系列课程1-技术篇 架构设计原则
本篇文章是《如何成为SM系列课程》的技术篇第一篇,这个系列文章会从技术、管理、业务三部分分章节和大家介绍如何从这3方面着手,成为一名懂技术、懂管理、懂业务的Scrum Master,本系列主要是针对传统项目经理进行分享经验,在我们公司内部调研的时候发现传统项目经理在这3块中最担心的是技术部分,所以本系列我也从技术开篇,因为项目经理转SM,并不会实际参与到代码开发中,所以这里会介绍架构的设计原则、设计流程和一些银行系统中常见的套路架构设计,同时也会拿一个技术方案给大家进行详细讲解,让项目经理能够看懂技术方案、能够了解架构要点,最终能够自己产出技术方案,这篇就从架构设计原则开始讲述。
合适原则
设计任何IT系统架构要遵循 “合适优于业界领先”的合适原则。能力较强的技术人员都有很强的技术情节,当他们做方案或者架构时,总想不断挑战自己,要求系统达到甚至高于业界领先水平,因为只有这样才能体现自己的能力,才能在年终绩效考核报告里写上自己参与了某某系统的设计和方案制定,并经过压测在保证高可用的情况下达到了某某大厂的性能指标。
但实际情况是大部分这样设计的架构最后可能都是以失败告终。为什么会失败?
再好的方案,也需要一步步稳扎稳打去实现,这里的稳扎稳打主要体现在以下几点:
1)人员结构和人员规模
大公司因为人员能力较强,开发人员规模较大,因此整体的分工较细,一个小模块就是一个十来人的小组来负责,一些常用的中间件也都有专门的中间件团队进行维护,而实际上大部分公司,整个研发团队可能就只有几十人,某些业务开发团队可能只有几个人,几个人想做几十个人规模的团队做的事情,难度可想而知,所以合适原则是结合目前公司的人员情况来定义的。
2)架构优化是个长期的过程
业界很多优秀的方案,并不是某个时期灵光乍现,然后突然设计出来的,而是经过几年时间的发展才不断完善和调整出来的。很多大厂的中间件团队都是通过多年的学习和成长才能有现在这些成果。这些优秀的系统架构方案也都是通过踩了无数的坑才总结和提炼出来的。这些挑战和踩坑,都是架构设计非常关键的促进因素,单纯靠拍脑袋或者头脑风暴,是不可能和真正实战相比的。没有一定的积累是不可能形成一个优秀的架构方案的。
3 )优秀架构是被业务倒逼出来的
可能有人认为,业界领先的架构方案都是天才架构师创造出来的,所以为了证明自己,自己也要创造出一个牛逼的架构,这样的天才架构师确实存在,但是很多时候,这些优秀的架构方案都是被倒逼出来的。简单说就是业务发展到一定阶段,量变导致了质变,出现了新的问题,已有的方式已经不能应对这些问题,需要一种全新的方案来解决问题,通过创新和尝试才有了业界领先的方案。
所以,真正优秀的架构都是在企业当前人力、物力、业务等各种条件下设计出来的,能够合理的将资源整合在一起并发挥出最大功效,并且能够快速落地。很多大厂的架构师在小规模创业公司单纯的套用大厂的架构方案,反而会失败,因为没有了大厂的资源和积累,生搬硬套大厂方案很容易导致失败。
简单原则
很多新架构师都会想把架构设计的更加精美细致,这必然会导致一个问题,就是将架构做复杂了,新人架构师会认为只有所有架构细节都考虑到了,才能体现出自己的价值和技术实力。
团队的压力有时也会有意无意的促使架构设计走向复杂的方向,因为大部分人在评价一个方案水平高低的时候,复杂性是其中一个重要的指标。例如一个主备方案,如果你用心跳来实现,可能大家都认为太简单了。但如果你引入zookeeper来做主备决策,可能很多人会认为这个方案更加可靠更加牛,毕竟zookeeper使用的是Paxos算法,Paxos本身就特别复杂,能理解的人很少。这个例子想表达的含义是新人架构师,在潜意识中就会去追求架构的复杂性。然而,复杂的架构在制造业代表着先进,在建筑行业代表着领先,但在软件领域,却恰恰相反,代表着架构的复杂和潜在隐患。
IT系统的复杂性主要体现在以下两方面:
1)结构的复杂性
结构复杂的系统几乎毫无例外的具备两个特点:
- 组成复杂系统的组件数量很多;
- 同时这些组件之间的关系也更加复杂。
结构上的复杂性存在的第一个问题是,组件越多,就越有可能其中某个组件出现故障,从而导致系统故障。这个概率可以算出来,假设组件的故障率是10%,那么有3个组件的系统可用性是90%*90%*90% = 72.9%,有5个组件的系统可用性是90%*90%*90%*90%*90% = 59%,两者的可用性相差13%。
结构上的复杂性存在第二个问题是,某个组件的修改,会影响关联的所有组件,这些被影响的组件同样会继续递归影响更多的组件。这个问题还会影响整个系统的开发效率,因为一旦变更涉及外部系统,需要协调各方统一进行方案评估、资源协调、上线配合。
结构上的复杂性存在的第三个问题是,定位一个复杂系统中的问题比简单系统更加困难。首先是组件多,每个组件都有嫌疑,因此要逐一排查;组件间的关系复杂,有可能表现故障的组件并不是真正的问题的根源。
2)逻辑的复杂性
结构的复杂性的解决办法是减少组件数量,最简单的结构当然是整个系统只有一个组件,所有的功能和逻辑都在一个组件中实现,这就是我们常说的单体应用。如果只是将复杂的多组件结构,粗暴的缩减到只有一个组件,这样做显然是行不通的,原因在于除了结构的复杂还有逻辑的复杂性,即如果某个组件的逻辑太复杂,一样会带来各种复杂度导致的问题。
逻辑复杂几乎会导致软件工程的各个环节都有问题,假设现在淘宝将所有功能集成在一个单体应用中实现,那么下面这些场景都会导致问题:
- 该系统非常庞大,可能是上百万、上千万的代码规模,clone一次代码要半小时,编译一次代码要1小时。
- 上百人维护一套代码,某个开发人员不小心改错了一行代码,导致整个网站崩溃。
- 并行需求多了以后,需要拉十几个甚至几十个开发分支,然后各种分支合并,各种分支覆盖。
- 产品、研发、测试、项目管理不停的开会讨论版本计划、协调资源,解决冲突。
- 版本太多,每天都要上线版本,系统每隔几个小时就要停机上版本。
- 线上运行出现故障,几十个人一起定位问题,堡垒机都不够用的,整个机房像菜市场一样。
综上所述,我们可以发现无论是机构的复杂性还是逻辑的复杂性,都会存在各种问题,所以在架构设计时,如果简单的方案和复杂的方案在短期内(1年左右)都能够满足需求的时候,最好选择简单的方案。
演化原则
软件架构和建筑架构非常类似,软件架构描述的是一个软件系统的结构,包括各个模块,以及这些模块的关系;建筑架构描述的是一幢建筑的结构,包括各个部件,以及这些部件如何有机的组成一幢完美的建筑。
然后软件和建筑有个本质的区别,建议一旦完成,就不可能再变,而软件却需要根据业务的变化不断变化。对建筑来说,永恒不变是主题;而对于软件来说,拥抱变化才是主题。软件架构需要根据业务的发展而不断变化。就算是林纳斯这样非常牛的软件工程师,也没办法在30年前直接设计出目前的linux,他也是从0.0.1版本开始不断迭代根据用户需求不断优化而来的。
如果没有把握“软件架构需要根据业务发展不断变化”这个本质,在做架构设计的时候就很容易陷入一个误区,试图一步到位设计一个软件架构,期望不管业务如何变化,架构都稳定如初。为了实现这样的目标,要么照抄大厂的架构方案,要么投入巨大的资源和时间来做各种预测、分析、设计。无论哪种做法,最后的结果都很明显,投入巨大,落地困难。
软件架构需要根据业务发展不断变化这个特质,来设计软件架构:
- 首先,设计出来的架构要满足当前和短期内业务的需求;
- 其次,架构要不断在实际应用过程中迭代,保留优秀的设计,修复有缺陷的设计,改正错误的设计,去掉无用的设计,使得架构逐渐完善。
- 当业务发生变化时,架构要扩展、重构,甚至重写,代码也许会重写,但有价值的经验、逻辑、设计等却可以在新架构中延续。
架构师在进行架构设计时需要时刻提醒自己不要贪大求全,过分追求完美架构。应该认真分析当前业务的特点,明确业务面临的主要问题,设计合理的架构,快速落地以满足业务需要,然后在运行过程中不断完善架构,不断随着业务演化架构。
淘宝架构演进
该章节很多内容来自于《淘宝技术这十年》
第一代技术架构LAMP
淘宝在2003年4月成立,2003年5月第一版淘宝就仓促上线,这么短时间要上线一个电商系统,需要包含商城官网、商户后管、库存模块、支付模块等等那么多功能,那么只能通过最快的买的方式买一套现成的系统,淘宝的第一个版本就是买来的当时市面上非常常见的LAMP架构的一个网上商城。
当时的淘宝第一目的是要快速上线对标当时的对手易趣,所以当时在技术面没有考虑技术是否有强扩展性、高性能、高可用,主要的考虑因素是什么时候能够上线。我们现在设计很多系统的架构时候也是需要有这方面的考虑,对于一些业务市场前景特别好,业务部门评估下来几个月后才上线可能会错过市场机会,对公司市场占有率会产生非常大的影响,那么可以考虑和第一版淘宝一样,采用急用先行原则,设计一个不是那么完美的架构,先满足业务需求再考虑后续的架构迭代优化,但是这里作为架构师一定要注意,很多架构师会把这些临时架构方案作为了未来的长期方案,在制定这样临时架构的时候一定要提前知道该架构的缺陷和瓶颈在哪,一旦遇到业务飞速发展,需要能够在短时间内找出好的优化方案,要留好后手。
淘宝的第一代架构如下图所示,开发语言使用PHP,应用服务器使用的是Apache,数据库采用的是Mysql读写分离方案,整体架构方案非常简单,这里的架构设计和选择主要遵循的是合适原则和简单原则。
monkey 2019-08-05 10.07.51第二代技术架构LAOP
随着业务的快速发展,到了2003年底数据库IO层面就吃不消了数据库成了整个商城的最大的性能瓶颈,当时的Mysql功能还比较弱,就算做了读写分离单库的读写性能也比较弱,当面临大数据量和高并发请求的时候,数据库成了最大的性能节点,所以当时淘宝技术团队为了最短时间解决问题,直接将底岑数据库替换成了Oracle,替换Oracle除了它承载的容量更大、稳定、安全、性能高,还有当时Oracle 的DBA比较好招,Mysql在当时很难招到DBA,基本都是靠自学和社区。
在第二代技术架构中,主要是针对数据库进行了替换,由Mysql主从读写分离架构替换成了Oracle单库,并且使用了PHP社区开源的数据库连接池代理库SQL Relay,作为应用服务端的数据库连接池来提高数据库连接的利用率。
monkey 2019-08-05 10.10.28第三代技术架构Java 1.0
淘宝的业务量不断飞速发展,使用PHP脚本语言的弊端逐渐体现出来,一方面是PHP本身是脚本语言,导致从根本上性能是存在脚本语言通病执行性能瓶颈的;另一方面使用的开源PHP数据库连接池SQL Relay存在死锁问题,经常出现死锁,死锁了就必须重启,应用服务器一旦重启就会导致停止服务,这是业务不能接受的,尤其在业务高速发展的时候时不时出现服务不可访问,必然导致口碑的下降和客户的流失。在04年正是java的进入中国的黄金年代,当时从学校到社会,几乎所有人都在学习Java,并且Java社区非常的活跃,招聘比较容易,后续维护成本比较低。
第三代的技术架构的变化是巨大的,整体的技术栈做了巨大的变化,开发语言从PHP变成了Java,并且是全套系统自研,使用的Java框架也是当时主流的EJB,应用服务器使用了WebLogic,数据库访问也使用了ORM框架,整体使用的技术栈和那个年代的主流技术是完美契合的。这时候淘宝已经不再是通过买来解决问题了,而是通过技术重构来解决问题,架构设计和选择遵循了演化原则。
monkey 2019-08-05 10.11.55第四代技术架构Java 2.0
随着交易量的迅速膨胀,2005年淘宝的商品数达到了1600万,PV达到了9000万,传统的基于EJB的J2EE架构已经不能满足要求,这时候内部又发起了系统重构,这次系统重构的核心是系统拆分、数据分库、放弃EJB、引入Spring、引入缓存、加入CDN、使用JBoss等。这些重构,看起来没有章法可遵循,其实都是围绕着提高容量、提高性能、节约成本来做的。
原有的方案存在固有缺陷,Oracle再强大也会存在单库性能的天花板,并且Oracle是非常贵的,当只有几台Oracle数据库服务器的时候,可能对成本并不怎么关心,但是如果要买100台、1000台的时候,成本就是一个非常需要关注的问题了。当业务和系统发生巨大变化后,架构设计就需要遵循演化原则,再进行一次重构甚至推到重来。
monkey 2019-08-05 10.12.56第五代技术架构Java 3.0 分布式架构
又经过了两年的快速发展,淘宝技术进入了技术飞跃的阶段,淘宝技术团队从原先是一哦那个商用软件转为自研,也就是最近几年国内大家都在叫的去IOE。淘宝的中间件团队开始研发各类分布式中间件,淘系的技术栈除了支撑自身的海量业务,也开始影响整个互联网社区和中国互联网技术的发展。现在不管是互联网公司还是传统行业,基本上都能在运行的代码中看到阿里中间件的影子。
monkey 2019-08-05 13.44.00
第六代技术架构 云上分布式
淘宝随着每年业务量不断的发展,传统的IDC已经不能满足目前的弹性伸缩的需求了,从2010年开始,淘宝网重点着眼于统一架构体系,从整体系统层面考虑开发效率、运维标准化、高性能、高可扩展性、高可用、低成本方面的要求,底层的基础架构统一采用了阿里云计算平台,使用了SLB、ECS、RDS、OSS、ONS、CDN等阿里云计算服务,并通过阿里云服务提供的高可用特性,实现双机房容灾和异地机房单元化部署,为淘宝业务提供稳定、高效和易于维护的基础架构支撑。在最近几年淘宝是阿里集团第一个整体迁移到阿里云的子公司,随着淘宝网全渠道全面切换到阿里云,淘宝又实现了一次底层技术的飞跃,整体实现了云端架构,随后天猫、阿里巴巴、聚划算、支付宝等子公司也都逐步迁移到了阿里云上。
第六代的技术架构也再次印证了演化原则。
monkey 2019-08-05 13.54.03
总结
介绍了架构设计的3个原则合适原则、简单原则、演化原则,这就是我们在架构设计过程中指导架构师设计架构的核心思想,所有的架构设计都可以按照这样的顶层思路去设计架构,最后也通过淘宝技术架构的演进来讲述这3个原则在淘宝10年架构演进过程中的体现。因此所有的系统架构设计只要遵循这3个原则就能保证我们系统整体架构是符合当时业务需求和未来业务发展的。