愿景已经确定架构愿景和目标。
需求分析明确架构要解决当前什么问题。
那接下来就是如何着手开始做架构设计。
一、如何开始设计一个架构:方式方法
架构不是像平常写代码一样,对就是对,错就是错,它并无对错之分,是一个取舍的过程。当我们从0开始做架构的时候,的确是比较困难。虽然万事开头难,但是一个好的开始相当于成功了一半,会给我们接下去的工作打下结实的基础。
我的经验步骤是:业务->功能->技术实现->架构综览图
1、业务架构:确定总体架构,核心流程, 是最上层的战略架构.
包括业务规划,业务模块、业务流程,对整个系统的业务进行拆分,对领域模型进行设计,把现实的业务转化成抽象对象。
没有最优的架构,只有最合适的架构,一切系统设计原则都要以解决业务问题为最终目标,脱离实际业务的技术情怀架构往往会给系统带入大坑,任何不基于业务做异想天开的架构都是耍流氓。
所有问题的前提要搞清楚我们今天面临的业务量有多大,增长走势是什么样,而且解决高并发的过程,一定是一个循序渐进逐步的过程。 合理的架构能够提前预见业务发展1~2年为宜。这样可以付出较为合理的代价换来真正达到技术引领业务成长的效果。
2、应用架构:确定子系统的功能范围和划分解决方案:
应用作为独立可部署的单元,为系统划分了明确的边界,深刻影响系统功能组织、代码开发、部署和运维等各方面. 应用架构定义系统有哪些应用、以及应用之间如何分工和合作。这里所谓应用就是各个逻辑模块或者子系统。
应用架构图关键有2点:
1、职责划分: 明确应用(各个逻辑模块或者子系统)边界
1)逻辑分层
2)子系统、模块定义。
3)关键类。
2、职责之间的协作:
1)接口协议:应用对外输出的接口。
2)协作关系:应用之间的调用关系。
应用分层有两种方式:
一种是水平分(横向),按照功能处理顺序划分应用,比如把系统分为web前端/中间服务/后台任务,这是面向业务深度的划分。
另一种是垂直分(纵向),按照不同的业务类型划分应用,比如进销存系统可以划分为三个独立的应用,这是面向业务广度的划分。
应用的合反映应用之间如何协作,共同完成复杂的业务case,主要体现在应用之间的通讯机制和数据格式,通讯机制可以是同步调用/异步消息/共享DB访问等,数据格式可以是文本/XML/JSON/二进制等。
应用的分偏向于业务,反映业务架构,应用的合偏向于技术,影响技术架构。分降低了业务复杂度,系统更有序,合增加了技术复杂度,系统更无序。
应用架构的本质是通过系统拆分,平衡业务和技术复杂性,保证系统形散神不散。
分久必合,合久必分,结合当前的实际资源情况做出最终的决策,这是整个过程中最耗时的点,它决定着架构的复杂度和开发成本。方式上包括但不限于抽出可重用的功能、功能的组合、拆分粒度更细的功能提高可重用性等等。这一切的决策都要以“恰到好处”为宜。千万不要盲目的跟从微服务之风!千万不要盲目的跟从微服务之风!千万不要盲目的跟从微服务之风!重要的事情说3遍。服务粒度越细,调用链路越复杂,带来的开发成本是否适合团队,是作为一个架构师需要着重考量的点。
系统采用什么样的应用架构,受业务复杂性影响,包括企业发展阶段和业务特点;同时受技术复杂性影响,包括IT技术发展阶段和内部技术人员水平。业务复杂性(包括业务量大)必然带来技术复杂性,应用架构目标是解决业务复杂性的同时,避免技术太复杂,确保业务架构落地。
3、技术架构: 技术调研, 确定系统核心技术点
1、技术选型: 根据业务场景, 了解业内的玩法,能不能解决现有问题. 比如使用微服务构建,dubbo,spring cloud.
2、评估技术成本: 结合业内的玩法与自有技术体系的结合成本,评估使用成本,推广成本.
例如要使用dubbo,评估现有开发人员能不能hold住, 重构成本有多大.
3、方案取舍: 技术方案有多种,了解每种方案优缺点, 让大家参与讨论.
4、确定系统核心技术方案:
技术架构最终是确定组成应用系统的实际运行组件(lvs,nginx,tomcat等),这些运行组件之间的关系,以及部署到硬件的策略。
技术架构还要考虑系统的非功能性特征,对系统的高可用、高性能、扩展、安全、伸缩性、简洁等做系统级的把握。
系统架构的设计要求架构师具备软件和硬件的功能和性能的过硬知识,这也是架构设计工作中最为困难的工作。
4、数据架构:
数据架构指导数据库的设计
5、架构总览图:
架构综览图,
这样能够帮助站在一个更高的角度去考虑架构的演变问题。如果是针对现存项目重新做架构,那么需要把现有项目架构梳理出来,作为我们上面思考过程中的一部分参考信息。
6,详细设计与实施
这个架构设计步骤即使就是套路,即方法论, 不论是大系统,还是单个应用系统, 都可以使用这个套路.
比如我们要设计一个微服务的订单系统:
1、业务: 确定业务流程: 确定订单关键功能点和流程
2、应用: 确定订单顶层设计,系统模块,对外暴露哪些接口. 接口协议形式.
3、技术: 确定使用哪些技术点: mysql, mongo,是否考虑分表分库. 使用哪些中间件.
4、数据: 如何设计表结构.
5、详细设计:
二、技术选型: 指导原则
架构设计并没有像编程语言那样的语法约束,更多的时候是面多多种可能时的“选择”:
例如:
选先进的技术还是团队熟悉的技术?先进的出问题怎么办?熟悉的后续技术演化困难怎么办?
用Angular还是React,一个很强大一个更灵活
MySQL还是MongoDB?
淘宝的电商架构咳哟简单的照搬么?
等等
但存在共性原则:合适原则、简单原则、演化原则
1、合适原则:合适优于业界领先
优秀人才的技术情节导致各种以先进技术主导的创业失败,原因有:
将军难打无兵之仗(人数)
罗马不是一天建成的(积累)
冰山下面才是关键(业务)
所以真正的优秀架构都是在企业当前人力、条件、业务等各种约束下设计出来的。BAT的架构师到小公司没有了大公司的资源、平台、积累和业务,只照搬大公司的做法和技术即会失败!
2、简单原则:简单优于复杂。
软件领域复杂度体现两个方面:
1)、结构的复杂性
组成复杂系统的组件数量更多
同时这些组件之间的关系也更加复杂
组件增多整体出现鼓掌的概率增加,可用性下降
某个组件改动会影响关联的所有组件
定位复杂系统的问题比简单系统更加困难
2)、逻辑的复杂性
单组件承担功能过多,导致逻辑复杂度升高
后续的功能修改会影响很大
使用了复杂的算法难以实现修改和问题解决
如果简单和复杂的都能满足需求,最好选择简单的方案!
3、演化原则:演化优于一步到位. 架构设计没有完美银弹. 勿过度设计.
软件架构同建筑架构相似,但建筑不可变,软件可变, 例如:Windows的演化、Android的发展。
软件架构类似于大自然“设计”的一个生物,通过演化适应环境,逐步变得强大。
首先满足当前需要,解决当前最核心问题.
预测并并发未来可能存在的问题, 不断迭代保留,不断完善,
业务变化时,架构扩展、重构、甚至重写。
不要贪大求全,分析清楚自身业务特点,快速落地,不断完善演化。当然如果一开始系统就有很好的基础设计, 未来可能更容易到达满意的目标.
所有问题的前提要搞清楚我们今天面临的业务量有多大,增长走势是什么样,而且解决高并发的过程,一定是一个循序渐进逐步的过程。例如在初创公司的野蛮生长阶段,业务场景和需求边界很难把握,有时候根本不需要架构师,产品需要快速迭代和变现,需求频繁更新,这个时候需要的是快速实现。这时候考虑如何做好架构设计, 如何微服务化, 可能会影响业务的发展.
整个系统进化分为三个阶段:
水平扩展阶段,通过负载均衡服务器不断的横向扩充应用服务器,水平扩展最重要的问题是需要注意不用服务器之间的如何保持session和会话同步,不能让用户在不通服务器之间切换时有感知应用扩展后自然遇到的问题就是DB的瓶颈:连接数,iops等。
就是对数据库的拆分,难度上了一个台阶,Sharding的基本思想就要把一个数据库如何进行切分,可以分为水平切分和垂直切分,水平切分相对简单,一主多从,多主都可以,根据业务的需要,多主切分设计时需要注意主键的关系,解决多写在进行数据同步时候的冲突问题,垂直拆分更加复杂,一般都会涉及到架构逻辑的改造,需要引入中间件,来进行数据源的管理,垂直拆分时把关系紧密(比如同一模块)的表切分出来放在一个库上,或者通过hash进行拆分,从而将原有数据库切分成类似矩阵一样可以无限扩充的队列。
最后就是功能分解了,也就是我们讲的微服务切分。微服务拆分将巨型应用按照功能模块分解为一组组不同的服务,淘宝的系统当年也经历了这样的过程,通过五彩石项目从单一的war包拆分成了今天的大家看到买家,卖家中心,交易等系统。
技术选型: 是否使用微服务架构设计
在司成长稳定以后, 业务模式和应用场景边界都已经比较清晰,这个时候最需要对线上业务进行模块划分,系统拆分重构,并做好相关高可用的措施,以保证系统的稳定,安全、高效地运行。这时候可能要考虑引入微服务.
在引入微服务前你要知道的事:
1、成本升高
引入微服务架构,需要对原来单一系统进行拆分,1到100以后多服务的部署会带来成本的升高**
2、解决分布式事务一致性问题
以前单一的系统好处很多,一条sql解决完成所有业务逻辑,微服务做完一件事情需要涉及多系统调用,系统间网络的不确定性给结果带来很多不确定性,如今天淘宝的系统,完成一次交易下单需要在上百个系统之间调用,如何保证系统的可靠性,以及核心数据如钱的最终一致性是设计之初就要想明白的,这里大多都要借助中间件来实现。
3、微服务的逻辑设计原则
随着不断拆分微服务,以及业务的迭代发展,系统之间极有可能出现混乱调用,所以微服务的顶层设计显得尤为重要,架构师需要搞清楚微服务的架构模型。那核心的设计思想就在于如何进行服务的分层,以及服务的重用,通过分层将服务进行分配,上层服务包装下层服务,下层服务负责原子性的操作,上层服务对下层服务进行业务性的组合编排,一定要理解业务,微服务拆分不是简单的系统组合,再说一遍一定要理解业务,否则上层服务一定会出现大量的交叉调用,系统复杂度会指数级上升,好的微服务架构师一定是业务架构师,基于业务的建瓴,微服务设计三部曲,遵循自下而上的设计原则:、
原子服务
首先确认最基本业务最维度的原子服务,原子服务定义就是大家都会最大化重用的功能,需要在应用内的闭环操作,没有任何跨其他服务的分支逻辑,杜绝对其他服务的调用,有自己独立的数据存储,作为最底层服务抽象存在,以淘宝为例,卖家数据,卖家数据,订单数据就属于最基本的原子服务。
服务组合
在业务场景下,一个功能都需要跨越多个原子服务来完成一个动作。组合服务就是将业务逻辑抽象拆成独立自主的域,域之间需要保持隔离,服务组合会使用到多个原子服务来完成业务逻辑,如淘宝的交易平台会调用用户,商品,库存等系统。
业务编排
最外层就是面向用户的业务流程,一个产品化的商业流程需要对组合服务进行逻辑编排来完成最终的业务结果,这个编排服务可以完全是自动化的,通过工作流引擎进行组合自动化来完成特定SOP定义,这对企业应用的自动化流程改进也很有意义。如淘宝类目的双十一活动,通过对不通服务组合进行重用实现不通的营销活动逻辑。
4、运维管理的复杂度提升
微服务让应用数量增加很多,链路的集成、测试、部署都成为新的挑战,以前一个war包解决的问题,需要通过多应用发布来完成,发布时服务之间的依赖影响,会导致功能不可用,测试阶段的依赖性可能会让用例跑不下去,这些都会是需要新考虑的问题,需要有平台化的工具来支撑,目前阿里通过aone产品来保证从日常到预发到线上的持续集成交付。