开发架构知识框架笔记总结
2022-10-31 10:12:27 0 举报
AI智能生成
登录查看完整内容
开发架构知识框架笔记总结
作者其他创作
大纲/内容
无架构,不系统
拓展你的职业发展空间
为什么开发人员要学习架构?
系统角度
业务角度
资源平衡
需要克服的挑战
理论
实战
如何找到一个好的学习方式呢?
如何学习架构?
架构的出发点是业务和技术在不断复杂化,引起系统混乱,需要通过架构来保证有序
分支主题
架构实现从无序到有序,是通过合理的内部编排实现的,基本的手段,就是“分”与“合”,先把系统打散,然后将它们重新组合,形成更合理的关系。
通过合理的内部编排,保证系统高度有序,能够不断扩展,满足业务和技术的变化。
从概念层面帮助我们理解系统面临哪些问题以及如何处理
讲清楚核心业务的处理过程,定义各个业务模块的相互关系
业务架构
从逻辑层面帮助我们理解系统内部是如何分工与协作的。
讲清楚系统内部是怎么组织的,有哪些应用,相互间是怎么调用的
应用架构
技术架构从物理层面帮助我们理解系统是如何构造的,以及如何解决稳定性的问题。
讲清楚系统由哪些硬件、操作系统和中间件组成,它们是如何和我们开发的应用一起配合,应对各种异常情况,保持系统的稳定可用。
技术架构
架构的分类
业务可扩展、可复用
业务复杂性
系统的高可用、高性能和可伸缩,并尽量采用低成本的方式落地
技术复杂性
好的架构要求
出色的程序员,写的一手好代码
架构师要有技术的广度(多领域知识)和深度(技术前瞻)
思维的高度,具备抽象思维能力,善于把实物概念化并归类
思维的深度,能够透过问题看本质
良好的沟通能力(感性)
良好的平衡取舍能力(理性)
能力模型图
好的架构师要求
架构本质
概述篇
从架构角度看,业务架构是源头,然后才是技术架构。
职责:告诉用户,系统长什么样子;告诉开发,他要实现什么功能。
目标:定义系统的外观,满足了用户
产品经理
职责:把业务流程和节点打散,按照业务域的维度来划分系统模块,并定义这些模块之间的关系,最终形成一个高度结构化的模块体系。
目标:定义系统的外观、满足了用户、定义系统的内部模块结构,满足了开发人员
业务架构师
业务架构师和产品经理区别
业务架构设计要能支持打造一个柔性系统,通过提供良好的业务扩展性,允许业务不断调整和快速生长。
特点:业务的主题是变化和创新,系统的主题是稳定和可靠。
案例
业务的可扩展
按照业务域来划分业务,把业务流程中的节点拆分到各个业务域,按照业务域构造系统模块
模块的职责定位要非常清晰
模块的数据模型和接口设计要保证通用
做好业务的层次划分
系统模块要求
业务的可复用
架构目标
概述
如何设计一个具有良好扩展性的系统,能够快速支持业务变化落地呢?
目标:如何打造一个善变的柔性系统?
快:如何快速地上线新业务?老板很可能明天就想看到效果。
稳:对某个功能进行修改,如何不影响到系统其它的功能?
常见问题
单体
分布式
传统的 SOA 架构:解决的是企业内部大量异构系统集成的问题
首先,它通过服务化思想,提供更好的业务封装性,并通过标准技术,能更友好地对外输出业务能力;
其次,SOA 服务不依附于某个具体应用,它可以独立地部署和扩展,这样避免了直接影响现有的系统;
最后,服务通过封装通用的业务逻辑,可以供所有应用共享,解决了重复造轮子的问题。
新的 SOA 架构:解决的是系统重复建设的问题
soa
微服务 = 小应用 + 小服务。
微服务
中台
发展过程
电商平台架构是如何演变的?
背景:先有pc,后有APP
优点:架构比较简单,App 的服务端整体上就一个应用,由移动团队来维护所有对外接口,服务端内部有很多 Jar 包,比如商品搜索、商品详情、购物车等等,这些 Jar 包包含了各个业务线的业务逻辑及数据库访问,它们由各个业务线的开发者负责提供。
移动服务端对 Jar 包的紧密依赖
移动团队的职责过分复杂
团队并行开发困难
缺点
架构图
V1.0 架构
优点:每块业务由不同的团队负责,可以很好地支持团队之间的并行开发;同时,移动接口和 PC 端共享底层业务逻辑,有助于快速把 PC 端的功能完整地复制到 App 端。业务线团队的生产力就被完全释放了,App 的功能也就快速丰富起来了。
移动端和 PC 端互相干扰的问题
重复开发的问题:系统级的功能,比如说,安全验证、日志记录、性能监控等等,每个移动接口都需要这些通用功能。
稳定性的问题:于这种直连方式,只要一个后端系统出问题,就会直接影响到 App 的可用性,使得 App 整体上非常的脆弱。
V2.0 架构
App 端和 PC 端彻底独立了
通过架构改造,实现了核心业务的复用
这个架构强化了系统级功能
团队分工也更明确了
效果
V3.0 架构
1 号店 App 服务端架构改造
定义:面向 C 端的应用,比如像微信、淘宝这样的应用。不过,你要注意,前台不仅仅是指前端,它还包含和前端配套的服务端
前台对外,我们知道,消费者的需求快速多变,所以前台需要能快速响应,做到低成本试错;
前台
定义:指的是企业内部系统,比如 ERP、CRM、仓库管理系统等等,主要是面向企业内部人员使用。对于传统企业来说,之前只有线下场景,通过内部的后台就能完成所有业务流程;而对于互联网企业,或者逐步开展线上业务的传统企业来说,同时需要前台和后台,一起协作,完成业务的闭环。
后台对内,企业内部的业务流程不能经常变,所以后台需要稳定,不能随意调整,一旦改动,影响面广,成本很高
后台
回顾
这个营销思路很棒,老板希望能马上验证,前台好改,但后台调整起来需要好几个月,互联网行业比较普遍
后台系统技术旧,性能差,接口不开放,前台对接起来很麻烦,而且一有促销活动,后台立马就挂。传统行业比较普通
前台要快,后台要稳,业务扩展时,常遇到以下两类挑战
如何实现前后台的平滑对接,这是一个巨大的挑战,中台架构因此而生。
Windows 系统
传统的线下业务
总部使用的 ERP、门店使用的收银系统等等
历史
外卖
小程序点餐服务
开辟新业务,新零售转型
背景
改造图
对内部老系统进行包装,对外提供标准的 API,这样就能把旧的 IT 基础设施,转换成面向互联网的业务平台
新的 C 端应用可以快速基于这个业务平台来构建,而不用关心底层老系统的实现细节。这个中间层就是中台
改造步骤
改造
麦当劳
例子
中台相当于企业的商业操作系统,通过对后台的包装,为前台提供全方位的支持。需要注意的是,中台不仅仅是前后台之间简单的适配器,中台本身也会落业务数据,有完整的业务规则,就像 Windows 操作系统一样,它在适配硬件的基础上,进一步提供内存管理、进程调度等功能,为上层应用提供体系化的支持。
传统行业
前后台虽然是同时建设的,它们在功能上能够衔接起来,但前台求快,后台求稳。所以在这里,中台可以先承接前台的业务和数据,和前台构成 C 端业务的小闭环,支持业务的快速创新,等业务模式验证后,中台和后台再进一步彻底打通,构成业务的大闭环。
互联网行业
中台定位
中台的适用性
从变化速度来看,企业基础的业务是相对固定的,而具体上层业务场景是相对多变的;
从数量来看,基础业务数量是有限的,而具体业务场景是无限的。
通过有限而比较固定的基础业务,来满足无限而快速变化的上层业务场景
从业务角度来看,中台收敛了业务场景,统一了业务规则
从系统角度看,中台相当于操作系统,对外提供标准接口,屏蔽了底层系统的复杂性
从数据角度看,中台收敛了数据,比如使用同一套订单数据模型,让所有渠道的订单使用相同的订单模型,所有订单数据落到同一个订单库。
企业级业务能力的快速复用
中台实现了通用基础业务的平台化的作用
在微服务架构下,我们搭建的是一个个离散的服务,如商品服务、订单服务等等。而在中台里,这些微服务升级为了商品中心、订单中心,每个中心更强调体系化,包括更好的业务通用能力,更好的系统运营能力(如监控、稳定性、性能的强化),更好的业务运营能力(比如商品中心自带配套的商品管理后台)
每个服务中心都围绕核心业务,自成体系,成为一个微内核,这些微内核形成一个有机整体,共同构成了基础业务平台,也就是中台。松散的微服务 -amp;gt; 共享服务体系 -amp;gt; 中台,这是微服务架构向中台架构的演进过程。
中台是微服务的升级版
基础业务能力由通用基础业务平台来实现
通用聚合服务对基础业务进行组合,进一步提升了业务能力的易用性
通用中间件平台,通过技术手段保证了业务中台的稳定性,三者一起实现了企业整体业务能力的复用
业务中台三层结构
概念
对于大的互联网企业来说,系统已经是类似于“山”字型的结构,进化到中台,更多的是各个基础服务点上的强化和面上的整合
整个系统的对外部分,包括了各个应用的前端,如 App、小程序、公众号等等,这些是需要定制的部分。同时,在对外部分,我们还会提供 Open API,供上下游企业调用
渠道 amp;amp; 应用
是各个具体应用的母体,它包含了各个应用的服务端,比如小程序服务端、App 服务端等等,这些服务端会针对具体场景,做流程编排和信息的聚合
应用平台
是中台架构的核心,它包括一系列的通用基础服务,以及它上面的通用聚合服务和下面的技术平台
业务中台
第一部分是适配插件,用于连接商户内部系统和中台基础服务,比如,在中台的商品服务和后台 ERP 之间同步商品数据,在中台的会员服务和后台 CRM 之间同步会员信息。一般针对每个内部系统,都有一个适配插件,它起到了类似硬件驱动程序的作用,这个一般是定制化的
第二部分是企业内部系统,这个是企业的 IT 基础设施,业务最终会在这里落地。
传统企业中台架构设计图
对于传统企业来说,系统基本上是“川”字型的结构,大量独立的商业套件组成遗留系统,落地中台是一个革命性的动作。
落地
如何落地?
你真的需要一个中台吗?
模块是系统的基本组成部分,它泛指子系统、应用、服务或功能模块。关系指模块之间的依赖关系,简单地讲,就是模块之间有调用,我们知道,调用区分发起方和服务方,因此,依赖关系是有方向性的。
系统的构成:模块 + 关系
模块定义系统都有哪些基本的“玩家”,分别承担什么职责。从业务的角度看,每个模块都代表了某个业务概念,或者说业务领域。
模块内部由数据和业务逻辑组成,其中数据是核心,业务逻辑围绕着数据,对数据做进一步加工,方便外部使用。
定位:保证模块业务概念的完整性。数据上,模块需要覆盖对应业务领域的全部数据,比如一个订单模块,它要覆盖所有渠道的订单,包括三方平台的订单、自有商城的订单、线下门店的订单等,这些不同类型订单的数据模型和实际数据,都由订单模块负责。
功能:模块要包含业务领域的全部功能,比如订单模块包含所有订单相关的功能,包括订单数据的增删改查、订单业务规则校验、订单的状态和生命周期管理等。
定位明确,概念完整。
自成体系:模块的业务逻辑尽量围绕自身内部数据进行处理,对外部依赖越小,模块的封装性越好,稳定性也越强,不会随着外部模块的调整而调整。
粒度适中:不能为了追求定位清晰,把粒度划分得很小,导致系统的碎片化。
自成体系,粒度适中。
打造可扩展要求
模块
关系定义了模块如何协作,一起完成业务流程,依赖关系实质上体现的是模块的组织结构。
单向关系
简化依赖的方向
我们按照模块定位的不同,把模块划分为不同层次,比如划分为上面的应用层和下面的资源层。这样,一个层通过把多个模块组织在一起,就形成了概念上更大粒度的模块。有了层以后,我们理解业务时,因为模块定位相同,往往关注这个更大粒度的层就可以,依赖关系只要指向这个层,而不是层里面的各个模块。这样,从人理解业务的角度,依赖的数量大幅度地减少了。
借鉴做法
MVC 架构:表示层、应用层、聚合服务层、基础服务层
具体例子
网状结构转化为层次结构
减少依赖的数量
简化模块的依赖关系
关系
系统构成
业务总在变化,要求架构设计给系统提供良好的扩展性。
表象
一个新需求,不仅要考虑功能实现,还需要考虑非功能要求,如:系统复杂度
深层
通过构建合理的模块体系,有效地控制系统复杂度,最小化业务变化引起的系统调整。
扩展性的本质
定义:从上到下把系统分为多层,按照系统处理的先后顺序,把业务拆分为几个步骤。
使每一块职责都比较明确,功能内聚,每个模块管理自己内部的复杂性
模块之间相互松耦合,一个模块的修改不影响另一个模块
很好地满足现有业务做深度扩展,当业务有变化时,系统在特定层做调整,对其他层影响有限,这样把变化局限在一个小范围
优点
水平拆分
定义:是按照不同的业务线拆分,按照不同的业务场景,自上而下进行竖切,让每个业务都自成体系,形成自己的业务闭环。
满足业务广度上的扩展
垂直拆分
一般做业务架构时,我们先考虑垂直拆分,从大方向上,把不同业务给区分清楚,然后再针对具体业务,按照业务处理流程进行水平拆分。
拆分:实现模块划分
定义:通过抽象设计,让一个模块具备通用的能力,能够替代多个类似功能的模块
优点:模块的数量减少了,模块的定位更清晰,概念更完整,职责更聚焦。在实践中,当不同业务线对某个功能需求比较类似时,我们经常会使用这个手段。
通用化
定义:把定位相同的模块组织在一起,以组团的方式对外提供服务。对于外部系统来说,我们可以把这些模块看成是一个整体,一起对业务场景提供全面的支撑。
平台化
整合:优化模块依赖关系
打造可扩展的模块体系
可扩展架构
好不容易搞定了一个项目,接着又有新的类似项目过来,我们又要从头再来
项目的代码是定制的,项目结束后,系统维护的噩梦刚刚开始
问题
技术复用:代码复用和技术组件复用
针对细分的业务领域,比如订单、商品、用户等领域。它对各个业务领域的数据和业务规则进行封装,将它变成上层应用系统可以直接使用的业务组件
业务实体复用
针对的是业务场景,它可以把多个业务实体串起来,完成一个端到端的任务。比如说,下单流程需要访问会员、商品、订单、库存等多个业务,如果我们把这些调用逻辑封装为一个下单流程服务,那下单页面就可以调用这个流程服务来完成下单,而不需要去深入了解下单的具体过程。
业务流程的复用
系统的复用,比如说一个 SaaS 系统(Software-as-a-Service),它在内部做了各种通用化设计,允许我们通过各种参数配置,得到我们想要的功能;
产品复用
业务复用:业务实体复用、业务流程复用和产品复用
复用的分类
从技术复用到业务复用,越往上,复用程度越高,复用产生的价值也越大,但实现起来也越复杂,它能复用的场景就越有限。
如果我们能进一步打造业务中间件,并在这个基础上,形成业务平台,这样,我们就能实现更高的业务级复用,可以更高效地支持系统的快速落地。
产品复用 amp;gt; 业务流程复用 amp;gt; 业务实体复用 amp;gt; 组件复用 amp;gt; 代码复用
复用程度排序
要解决“我是谁”的问题,它实现了服务和周边环境的清晰切割
服务包含了业务数据和业务规则,并提供接口给外部访问,其中,接口是服务的对外视图,它封装了服务的业务数据和规则
定义
服务内部数据的完整性,如商品,不仅包含商品基本信息,还需要包含商品扩展信息(标签),最后还要包含复杂商品类型(组合商品、套餐商品等)
服务功能的完整性,对于服务使用者来说,他们是以业务的角度看服务,而不是纯粹的数据角度。比如一个套餐商品,在服务内部,它是多个单品的复杂组合,但从服务调用者的角度来看,它就是一个商品
服务的完整性原则:保证服务数据完整、功能全面,这样才能支撑一个完整的业务领域
服务内部的业务逻辑要尽量依赖内部数据,而不是接口输入的数据,否则会造成数据和业务规则的脱节(一个在外面,一个在里面)
促销服务负责促销规则的维护,以及对应的优惠计算功能
订单服务负责优惠结果数据落地,以及后续的查询功能
举例:订单里的优惠信息,如:商品原价多少、满减优惠多少、特价减多少
服务的一致性原则:服务的数据和职责要一致,谁拥有信息,谁就负责提供相应的功能
基础服务,它们就处于调用链的底层,服务之间不会有任何的调用关系,也就是说基础服务相互之间是正交的。比如说会员服务和商品服务,它们代表不同维度的基础业务域,彼此之间不会有调用关系
服务之间有数据的依赖关系,但没有接口的调用关系,如:订单明细里包含商品 ID 信息,但订单服务内部不会调用商品服务来获取商品详情。如果页面需要展示订单的商品详情,针对这个具体的业务场景,我们可以在上层的聚合服务里,通过聚合订单服务和商品服务来实现
正交原则
原则
基础服务边界划分
服务边界确定了这个服务应该“做什么”
服务边界的划分
抽象设计确定了这个服务应该“怎么做”
功能的抽象设计
落地共享服务核心
订单业务架构
基本信息管理
从最开始的商品金额,到最后需要用户实际支付的金额,中间会有一系列的折扣和减免,这些都是属于订单信息的一部分。这些信息我们需要展示给用户看,如果后续要进行订单成本的分摊,也需要用到它。
订单优惠管理
负责管理订单的状态变化
订单生命周期管理
包含的服务
订单的用户详情、商品详情等等,这应该由上层应用通过调用相应的服务来实现,然后和订单信息组装在一起,而不是在订单服务内部直接调用其他服务,否则会导致基础服务之间相互依赖,职责模糊。
作为基础服务,订单服务不主动调用其他服务
第三方系统,太不具有通用性
订单服务不负责和第三方系统的集成
订单服务不提供优惠计算或成本分摊逻辑
不提供履单详情,不负责详细物流信息的存储
不包含的服务
订单服务边界划分
订单数据模型
优点:订单状态及规则是完全由外部负责管理的,自己负责属性存储,订单服务很稳定
弊端:上层应用的负担会很重,不但要负责定义有哪些状态,而且还要维护状态的转换规则,一不小心,订单可能从状态 A 非法地变成状态 B,导致业务出问题
开放订单状态定义
主状态,由订单服务负责定义
比如,一个订单处于配送中,实际情况可能是“仓库已发货”,“货已到配送站”,或者是“快递员正在送货中”等等
子状态,开放给各个应用来定义
应用和服务共同管理状态
订单状态通用化
粗粒度接口
中粒度接口
细粒度接口
设计查询接口,来满足各种场景需求
同步的服务接口调用
胖消息,不建议提供,效率低,一般采用瘦消息+查询接口
瘦消息
异步的消息通知
订单服务接口定义
功能抽象设计
订单服务
如何设计一个基础服务
所有商品相关的表都存在产品库里面,有产品的表(产品、分类、品牌、组合关系、属性等)、商品 SKU 的表、商家和供应商的表、库存和价格的表等等,这些表加起来,数量超过了上百张。
系统是类似分布式的,但数据库是集中式,前后台系统都需要访问产品库
从应用方面来说,各个系统功能重复建设,比如很多系统都会直接访问库存相关的表,类似的库存逻辑散布在很多地方;另外,如果修改了库存表的某个字段,这些系统同时会受影响,正所谓牵一发而动全身
从数据库方面来说,数据库的可用性是比较差的,如果某个系统有慢查询,它就很可能拖垮整个产品数据库,导致它不可用;还有,这么多系统同时访问产品库,数据库的连接数也经常不够用
痛点
对这个大数据库按照业务维度进行垂直拆分,比如分成产品数据库、库存数据库、价格数据库等等
基于这些拆分后的库,构建微服务,以接口的方式来支持数据库表的访问
将各个业务系统统一接入微服务,最终完成整个商品体系的微服务化改造
目标
背景和目标
业务价值大
改动小
挑选库存改造原因
满足所有的库存访问需求
表的数量不能太多
表的要求:既容易拆分数据库,又能控制服务的粒度,保证功能聚焦
确定库存微服务具体包含哪些表
确定服务的数据模型
确定服务的边界划分
圈表
收集所有业务系统访问这些表的 SQL 语句,包括它的业务场景说明、访问频率
收集 SQL
SQL 拆分,会涉及一定的业务系统改造及性能影响,需要评估
拆分 SQL
准备阶段
接口设计、代码开发、功能测试等步骤,服务开发团队会对业务方提供的 SQL 进行梳理,然后对接口做一定的通用化设计,避免为每个 SQL 定制一个单独的接口,以此保证服务的复用能力。
构建库存微服务
接入库存微服务
数据库独立
实施阶段
效果图
过程
库存微服务改造
1 号店库存服务化改造
业务上有什么重大变化,导致当前系统的弊端已经很明显,不能适应业务发展了呢?
架构改造时,如何在业务、系统、资源三者之间做好平衡,对系统进行分步式的改造呢?
系统架构是否需要升级的判断依据
为大型餐饮连锁企业打造 O2O 交易平台,包括三方聚合外卖、自有小程序、App 点餐,这些线上用户的订单最终会落到门店的收银系统,由门店进行履单。
只有聚合外卖服务v1版
小程序订单和外卖订单的处理类似,收银系统除了对接外卖系统,同时也对接小程序的订单服务。但这样一来,收银系统需要同时对接两套订单接口,它需要做大的改造。由于这是第三方的系统,我们在实践中很难落地。
我们把小程序订单当作一个特殊的外卖渠道,把小程序订单推送到外卖订单库里,最终还是由外卖系统来对接收银系统,也就是相当于小程序订单直接借用了外卖订单的履单通道。
方案选择
增加小程序版本v2版
统一订单服务架构v3版
中台架构v4版
系统升级过程的架构
中台是如何炼成的
可复用架构
业务架构篇
不清楚系统整体的处理过程,当系统出问题时,不知道如何有针对性地去排查问题
系统设计时,经常忽视非业务性功能的需求,也不清楚如何实现这些目标,经常是付出惨痛的教训后,才去亡羊补牢
面对一个复杂的系统的困惑
系统的物理模型
负责系统所有组件的技术选型
确保这些组件可以正常运行
技术架构的职责
垂直扩展:升级硬件来提升处理能力
水平扩展:增加机器数量来提升处理能力
硬件的处理能力有限
容灾、多机房部署
硬件不是 100% 的可靠,它本身也会出问题
硬件的问题
中间件
系统级软件
软件组件
弥补了硬件的缺陷。比如 Redis 集群,通过数据分片,解决了单台服务器内存和带宽的瓶颈问题,实现服务器处理能力的水平扩展;
封装让我们可以更高效地访问系统资源。比如说,数据库是对文件系统的加强,使数据的存取更高效;
软件是硬件的延伸,给系统的优势
CAP理论
软件的问题
技术架构的挑战
技术架构就要选择和组合各种软硬件,再结合我们开发的应用代码,来解决系统非功能性需求。
软硬件本身有故障,比如机器断电,网络不通。通过容错机制解决
高并发引起的系统处理能力的不足,通过优化、限流、降级方案解决
可用性出问题常见场景
系统的高可用
常规的流量进来,但系统内部处理比较复杂,我们就需要运用技术手段进行优化。比如针对海量商品的检索,我们就需要构建复杂的搜索系统来支持。
高并发的流量进来,系统仍旧需要在合理的时间内提供响应,这就更强调我们做架构设计时,要保证系统的处理能力能够整体上做水平扩展,而不仅仅是对某个节点做绝对的性能优化,因为流量的提升是很难准确预计的。
保证合理的性能分两种情况
系统的高性能
系统的可伸缩和低成本
故障不可避免,但如何能第一时间发现问题,快速进行恢复保障业务的连续性是非常重要的。
可监控性
非功能性需求
做技术架构设计时,不能不顾一切地要求达到所有目标,而是要根据业务特点,选择最关键的目标予以实现。比如说,一个新闻阅读系统,它和订单、钱没有关系,即使短时间不可用,对用户影响也不大。但在出现热点新闻时,系统要能支持高并发的用户请求。因此,这里的设计,主要是考虑满足高性能,而不用太过于追求 4 个 9 或 5 个 9 的可用性。
技术架构的目标
网络和服务器出故障,网络出故障表明节点连接不上,服务器出故障表明该节点本身不能正常工作。
资源不可用
常规的流量进来,节点能正常工作,但在高并发的情况下,节点无法正常工作,对外表现为响应超时。
资源不足
这个主要体现在我们开发的代码上,比如它的内部业务逻辑有问题,或者是接口不兼容导致客户端调用出了问题;另外有些不够成熟的中间件,有时也会有功能性问题。
节点的功能有问题
故障点
高可用的总体解决思路
无单点设计针对的是节点本身的故障
冗余无单点
针对的是节点处理能力的不足
水平扩展
正面保障
柔性事务保证功能的基本可用和数据的最终一致
柔性事务
限流
降级
熔断
功能禁用
系统可降级:通过损失非核心功能来保证核心功能的可用
减少损失
通过监控,我们可以实时地了解系统的当前状态
系统可监控
架构设计原则
客户端到服务端通常是远程访问,需要解决网络的可用性问题
在接入层,使用成熟的 HA 方案,比如 Nginx、HAProxy、LVS 等负载均衡软件,能很好地支持双节点 +Keepalived 部署。
客户端 -amp;gt; 接入层
Web 节点的水平扩展
自动故障转移
系统的可降级(限流)
反爬虫
接入层 -amp;gt;Web 应用
系统的可降级(限流、业务开关)
Web 应用 -amp;gt; 内部服务
主从部署
读写分离
MHA 方案
VIP漂移
关系数据库
缓存
消息系统
访问基础资源
高可用手段
回滚
重启
加机器
处理事故有三板斧
用户在小程序上点餐并支付完成后,订单会先落到订单库,然后进一步推送到门店的收银系统;收银系统接单后,推送给后厨系统进行生产;同时返回小程序取餐码,用户可以凭取餐码去门店取餐或收取外卖。
大型餐饮公司的小程序点餐平台
前端小程序请求将会达到每秒 10 万 QPS
首日的订单数量会超过 500 万
保证用户的体验,系统整体的可用性要达到 99.99%。
促销活动
系统架构
项目背景介绍
储存静态的商品数据、图片
小程序端的 CDN 优化
Nginx 负载均衡
收银端的通信线路备份
前端接入改造
应用和服务的水平扩展
订单水平分库
异步化处理
主动通知,避免轮询
高可用系统改造措施
如何实现O2O平台日订单500万?
指的是从前端用户的访问速度出发,来监测系统的可用性,包括页面能否打开、关键接口的响应时间等等,用户体验监控一般结合前端的埋点来实现
用户体验监控
它是从业务结果的角度来看,比如说订单数、交易金额等等,业务监控也是最直观的,我们知道,如果业务数据没问题,系统整体也就没有问题。对于业务监控,我们一般是从数据库里定时拉取业务数据,然后以曲线的方式展示业务指标随着时间的变化过程。除了当前的曲线,一般还有同比和环比曲线。同比是和前一天的数据进行比较,环比是和一周前的数据进行比较,两方面结合起来,我们就能知道当前的业务指标有没有问题。
业务监控
指的是对自己开发的代码进行监控,比如接口在一段时间内的调用次数、响应时间、出错次数等等。更深入一点的应用监控还包含了调用链监控,我们知道,一个外部请求的处理过程包含了很多环节,比如说网关、应用、服务、缓存和数据库,我们可以通过调用链监控把这些环节串起来,当系统有问题时,我们可以一步步地排查。有很多 APM 工具可以实现调用链监控,如 CAT、SkyWalking 等等。
应用监控
指的是对标准中间件进行监控,它是第三方开发的代码,比如数据库、缓存、Tomcat 等等,这些组件对应的是系统的 PaaS 层。这些中间件往往带有配套的监控系统,比如,RabbitMQ 就有自带的监控后台。
中间件监控
指的是对系统底层资源进行监控,如操作系统、硬件设备等等,这个层次的监控对应的是系统的 IaaS 层。Zabbix 就是典型的基础设施监控工具,它可以监控 CPU、内存和磁盘的使用情况。
基础平台监控
监控的分类
不同的节点,它的监控的方式是不一样的,相应地,监控的结果也在不同的系统里输出。
系统不同部分的监控都是由不同的人负责的,比如说,运维负责的是基础平台监控,开发负责的是应用系统监控。而监控信息往往专门的人才能解读,比如应用监控,它需要对应的开发人员才能判断当前的接口访问是否有问题
系统作为一个整体,需要上下游各个环节的人一起协作,进行大量的沟通,才能最终找到问题。
监控的痛点
业务监控的曲线一般 1 分钟更新一次,有时候因为正常的业务抖动,Monitor 还需要把这种情况排除掉。因此,他会倾向于多观察几分钟,这样就导致问题的确认有很大的滞后性
发现问题慢
系统节点多,大量的人需要介入排查,而且由于节点依赖复杂,需要反复沟通才能把信息串起来,因此很多时候,这种排查方式是串行或者说无序的。一方面,无关的人会卷入进来,造成人员的浪费;另一方面排查效率低,定位问题的时间长
定位问题慢
当定位到问题,对系统进行调整后,验证问题是否已经得到解决,也不是一件很直观的事情,需要各个研发到相应的监控系统里去进行观察,通过滞后的业务曲线观察业务是否恢复。
解决问题慢
系统能够自动地判断每个节点是否正常,并直观地给出结果,不需要经过专业人员的分析。
系统能够自动把各个节点的监控信息有机地串起来,从整体的角度对系统进行监控,不需要很多人反复地进行沟通。
对系统的监控要求
需要第一时间知道系统当前是否有问题
要实时
节点是否有问题,我们需要很直观地就能判断出来,就像交通图上的红黄绿颜色标识一样。
要直观
针对系统做整体监控,就像交通图一样,它是针对周边整体的道路情况进行展示,我们也需要把系统的各个节点放在一起,清晰地给出节点依赖关系。系统真正出问题的地方往往只有一个,其他地方都是连带的,如果监控系统能够给出节点的上下游依赖关系,对于定位真正的问题源是非常有用的。
整体监控
监控效果
系统中的每个节点对应交通图的一条道路
节点的健康状况对应道路的拥堵情况,节点同样也有红黄绿三种不同的颜色,来展示该节点是否正常;
节点之间的调用关系对应道路的方位关系
监控方式
解决思路
构建一个实时的、直观的、一体化的监控系统,类似交通图一样,可以一眼就看出系统的问题所在。
终极目标:故障自动定位(自动发现问题、通知故障处理、自动定位问题、故障处理、故障恢复)
监控系统的整体架构
如何第一时间知道系统哪里有问题?
节点信息采集
接入监控系统
前端信息展示
如何打造一体化的监控系统?
高可用案例
高可用架构
系统的 TPS 很低,只要流量一大,系统就挂,加机器也没用;
机器的资源利用率很低,造成资源严重浪费
常见场景
常用的性能数据
优化处理路径上每个节点的处理速度
并行处理单个请求,MapReduce思想
加快单个请求处理
同时处理多个请求
请求处理异步化
高性能的策略和手段
无状态的节点,增减节点实现
有状态的服务,能够支持状态数据的重新分布,复杂度高
节点级别的可伸缩
单元化处理,把相关的节点绑定在一起,同进同退
系统级别的可伸缩
实现方式
可水平拆分和无状态
短事务和柔性事务
数据可缓存
可异步处理
虚拟化和容器化
高性能和可伸缩架构原则
可伸缩的策略和手段
商品数量非常大
一瞬间会有大量的用户流量涌入,流量可以高达平时的几十倍
首先,我们对峰值流量的预估以及要加多少机器都是拍脑袋的,和实际出入往往很大,一旦估计少了,系统同样会面临过载的风险;
其次,为了短暂的几分钟促销,我们需要增加大量的机器,事先要做很多的运维准备工作,不但浪费资源,而且效率很低;
最为关键的是,有些处理节点,系统不是通过加机器就能扩展处理能力的,比如商品库存数据库,下单时,我们需要扣库存,而为了防止库存更新冲突,我们需要锁定库存记录,导致系统的并发处理能力有限,这个问题单靠加机器是解决不了的。
用户在商品详情页提交订单后,这个订单会作为预订单进入排队区,同时排队系统会返回用户一个排队编号,这个编号用于跟踪后续的订单处理进度;
用户被引导到一个等待页,这个页面会根据排队号,定时地查询排队系统,排队系统会返回预订单在队列中的位置信息,包括它前面还有多少未处理的预订单,以及后台系统大概还要多久会处理这个预订单,这样用户就不会焦虑;
在排队系统的处理区,有很多消费者,它们依次从排队区的队列里获取预订单,然后调用后台下单系统生成实际的订单;
随着预订单变成正式的订单,队列里的预订单会逐渐变少,如果当前的预订单已经从队列里被移除了,用户的等待页就会检测到这个情况,页面自动跳转到订单完成页,这就和常规的购物流程一样了,用户进行最后的支付,最终完成整个前台下单过程。
总体方案
排队系统使用的是 Redis,而不是 MQ。因为相对于 MQ 来说,Redis 更轻量级,性能更好,它内置了队列数据结构,除了和 MQ 一样支持消息的先进先出以外,我们还可以获取队列的长度,以及通过排队号获取消息在队列中的位置,这样我们就可以给前端反馈预订单的处理进度
为每个秒杀商品提供一个单独的队列
技术选型:redis
消费者优先从哪个队列里拿预订单,排队系统会结合下单时间和队列的长度来确定,以保证用户合理的时间体验。比如说,某个秒杀商品的队列很长,消费者会优先从这个队列拿预订单,从而避免用户等待太长的时间
队列的调度问题
为了保证用户能够买到商品,我们并不是把所有前台的下单请求都会放到队列里,而是根据参与活动的秒杀商品数量,按照 1:1 的比例,设置队列初始长度,这样就保证了进入队列的请求最终都能生成订单。
队列长度
队列
秒杀流程与常规购物流程隔离
活动商品库存的扣减非常频繁,把少量参与促销的商品种类单独放在一个库里,避免和大量常规的商品放在一起,这样也大幅度地提高了库存数据库的读写性能
活动库存独立存储
建立活动库存
高峰持续时间较长
用户对订单处理又有比较高的时间要求
不合适场景,如:外卖
内部设计
如何设计一个秒杀系统?
2013 年,随着 1 号店业务的发展,每日的订单量接近 100 万。这个时候,订单库已有上亿条记录,订单表有上百个字段,这些数据存储在一个 Oracle 数据库里。
垂直分库就是数据库里的表太多,我们把它们分散到多个数据库,一般是根据业务进行划分,把关系密切的表放在同一个数据库里,这个改造相对比较简单。
垂直分库
表太大,单个数据库存储不下,或者数据库的读写性能有压力。通过水平分库,我们把一张表拆成多张表,每张表存放部分记录,分别保存在不同的数据库里,水平分库需要对应用做比较大的改造。
水平分库
数据库拆分常见方法
分库维度怎么定?
数据怎么分?
分几个库
水平分库策略
数据太多,如何无限扩展你的数据库?
高性能和可伸缩架构
电商平台技术架构是如何演变的?
综合案例
技术架构篇
开发架构知识框架笔记总结
0 条评论
回复 删除
下一页