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