从零开始学架构V2-架构设计基础知识-3

说明

在了解完软件架构的基本设计原则、涉及流程,还需要补充一下架构设计中一些常见的基础知识,分为基础的技术知识、常见的软件架构都有哪些,本章节介绍的是基础知识。

一、数据库

单机的性能总是有限的,当业务发展到一定规模后,单机性能瓶颈问题就会日益凸显;当单机出现性能瓶颈时,常见应对方案就是更换配置更高的机器、增加机器、优化性能三种方式;

增加机器:我们常说的横向扩展。数据库与应用服务不同,应用服务一般不存储数据,仅做逻辑计算,复杂点在于服务注册、发现、负载均衡,解决这些之后只需要增加机器部署服务就可以了。数据库的横向扩展则需要对整体数据做拆分,然后将数据分散到多个机器上;当业务再次增长,原来多台机器性能不足以支持时,可能还需要对数据再次拆分。

优化性能:当单台机器的性能不够时,将一部分工作交给其他机器来处理;与增加不同,该方式是复用已有集群的能力,常见的实现就是读写分离。

接下来我们一起看看数据库的读写分离。

1.1 读写分离

定义: 读写分离,顾名思义将数据库的读、写操作分开,交给不同的机器来处理,处理结果与单台机器相同,那该如何实现呢?

当多台机器存储的数据完全相同,用户的请求直接交由任意一台机器处理都与原单机处理结果一致了;想要多台机器数据完全一致常见的方式就是一个写请求等所有机器都修改完毕再返回,这种方案性能未免有点差;简单优化一下:一台机器写操作完成就认为成功,由该机器异步同步其他到其他机器

此种方式也会引出新的问题:同步延迟,此问题下文会再次介绍;为了减少刚刚写机器的压力,一般会把读请求交给非写操作的机器。整理一下:我们将处理写操作的机器叫做主服务器,处理读操作的机器叫做从服务器,于是就可以得到下图:

在此架构中,数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据;主从架构使用一主一从、一主多从都是可以的,从机越多集群的读性能就越高,当然从机越多主机压力也会越大,数据延迟也会越明显;当主机挂掉后,可以在从机中选择一台机器顶替实现高可用。

任何架构都不会是十分完美的,读写分离亦是如此,主机同步从机是一个异步过程,存在一定的时间差,这样就会导致“主从延迟”问题,常见的解决方案是一致性要求较高的业务,读写请求都走主机,否则读请求还是走从机。

引入该架构还会带来复杂度问题:如何识别是读、写请求?如何将读请求转发给从机?主从故障节点发生变化后如何保障读写请求还是分配给主、从机器?公司有X个应用,如何降低改造成本?

数据库的操作都是通过SQL进行,只需要解析SQL很容易知道该操作是读还是写;

对于请求的转发,常见的实现有两种:

图一增加数据库代理,包装已有有的数据库集群,对外提供数据库的链接、请求处理、读写分离、分库分表、故障处理等。优点是改造成本较小,方便维护升级;缺点是所有请求都需要走代理,很容易成为系统瓶颈,本身也需要做高可用保障。

图二增加统一数据解析层,原系统应用访问数据库都需要经过该层,该层做SQL解析,对于读写分离架构、分库分表架构等,根据策略请请求发送到具体的机器上。优点是额外的机器成本较少,SQL解析、选库选表都在系统应用服务器上完成。缺点:改造成本大。所有应用都需要改造;功能迭代时,需要所有应用都一起升级。

对比主备架构

主从架构中“从机”的“从”可以理解为“仆从”,仆从是要帮主人干活的,“从机”是需要提供读数据的功能的;而主备架构中“备机”一般被认为仅仅提供备份功能,不提供访问功能。所以使用“主从”还是“主备”,是要看场景的,这两个词并不是完全等同的。

1.2 分库分表

“单机优化”介绍完毕后再开看看横向扩展:分库分表。

背景: 单个数据库服务器存储的数据量不能太大,需要控制在一定的范围内。为了满足业务数据存储的需求,就需要将存储分散到多台数据库服务器上。

1.2.1 分库

介绍: 分库指的是按照业务模块将数据分散到不同的数据库服务器

日常在电商平台购买商品时,大多都会进行搜索、浏览商品、下单、物流派送流程,其中涉及了商品、订单、履历等系统,按照业务模块可拆分成商品数据库、订单数据库、履约数据库等,不同的数据库分散到不同的数据库服务器上。

当数据库分散到不同服务上后,可能会对已有逻辑产生影响:如跨库的统计SQL;

1.2.2 分表

介绍: 分表是按照业务需求将大表拆分成多个小表,减少每次SQL检索数据块的大小、多少,从而提高整体性能。

垂直拆分: 按照业务需求将使用频率较低的字段拆分多个单独的表。

主要应用于宽表中,将一些不常用字段单独拆分出去。

横向拆分: 按照一定的算法将数据量特别大的表拆分成多个小表。

常见拆分方式:

  1. 范围拆分:选取有序的数据列(整型、时间戳等)作为路由的条件,不同分段分散到不同的数据库表中。以最常见的用户ID为例,路由算法可以按照100w的范围大小进行分段,(1,100w]放到表1中,(100w,200w]放到数据库2的表中,以此类推。
  2. Hash拆分:选取某个列(或者某几个列组合也可以)的值进行Hash运算,然后根据Hash结果分散到不同的数据库表中。同样以用户ID为例,假如我们一开始就规划了10个数据库表,路由算法可以简单地用user_id % 10的值来表示数据所属的数据库表编号,ID为985的用户放到编号为5的子表中,ID为10086的用户放到编号为6的字表中。
  3. 配置拆分:配置路由就是路由表,用一张独立的表来记录路由信息。同样以用户ID为例,我们新增一张user_router表,这个表包含user_id和table_id两列,根据user_id就可以查询对应的table_id。

当时数据拆分到多个表后,可能会对已有的逻辑产生问题:

  1. 使用聚合函数(count、sum、avg)等会导致数据统计不正确;
  2. 如果有排序,也会导致排序错误。
  3. 无法使用join

垂直拆分、横向拆分图例:

1.3 其他存储

K-V存储: 解决关系数据库无法存储数据结构的问题,以Redis为代表。 文档数据库: 解决关系数据库强schema约束的问题,以MongoDB为代表。 列式数据库: 解决关系数据库大数据场景下的I/O问题,以HBase为代表。 全文搜索引擎: 解决关系数据库的全文搜索性能问题,以Elasticsearch为代表。

二、负载均衡

定义: 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务或者网络请求)分摊到多个操作单元(服务器或者组件)上进行运行。目的是尽量将网络流量 平均 发送到多个服务器上,以保证整个业务系统的高可用。 作用:

  1. 高并发。通过采取一定的算法策略,将流量尽可能的均匀发送给后端的实例,以此提高集群的并发处理能力。
  2. 伸缩性。根据网络流量的大小,增加或者减少后端服务器实例,由负载均衡设备进行控制,这样使得集群具有伸缩性。
  3. 高可用。负载均衡器通过算法或者其他性能数据来监控候选实例,当实例负载过高或者异常时,减少其流量请求或者直接跳过该实例,将请求发送个其他可用实例,这使得集群具有高可用的特性。
  4. 安全防护。有些负载均衡器提供了安全防护功能。如:黑白名单处理、防火墙等。

2.1 分类

按照负载均衡的载体来分类可分为硬件、软件负载均衡。对软件负载细分,按照OSI网络分层模型来划分可以分为二层、三层、四层、七层负载均衡等。

2.1.1 硬件负载均衡

定义:通过单独的硬件设备来实现负载均衡功能。

优点:

  1. 功能强大:支持全局负载均衡并提供较全面的、复杂的负载均衡算法。
  2. 性能强悍:硬件负载均衡由于是在专用处理器上运行,因此吞吐量大,可支持单机百万以上的并发。
  3. 安全性高:往往具备防火墙,防 DDos 攻击等安全功能。

缺点:

  1. 贵。市面上常见的硬件负载均衡服务器有F5、A10,F5价格在15w~55w不等,A10价格在55w-100w不等,因此在大公司才会负担的起。
  2. 扩展性差:当访问量突增时,超过限度不能动态扩容。

2.1.2 软件负载均衡

软件负载均衡指的是在服务器的操作系统上安装负载均衡软件,从此服务器发出的请求经软件负载均衡算法路由到后端集群的某一台机器上。

常见负载均衡软件有:LVS、Nginx、Haproxy。

优点

  1. 扩展性好:适应动态变化,可以通过添加软件负载均衡实例,动态扩展到超出初始容量的能力。
  2. 成本低廉:软件负载均衡可以在任何标准物理设备上运行,降低了购买和运维的成本。 缺点
  3. 性能略差:相比于硬件负载均衡,软件负载均衡的性能要略低一些。

2.1.3 网络分层负载均衡

基于OSI网络分层模型,根据每层的特点进行负载均衡。

二层:数据链路层,该层在数据传输时根据MAC地址定位到唯一的设备,因此该层负载均衡的原理就是通过在通信协议的数据链路层修改mac地址。具体流程是让负载均衡服务器和业务服务器绑定同一个虚拟IP(即VIP),客户端直接通过这个VIP进行请求集群。集群中不同的机器采用相同IP地址,但是机器的MAC地址不一样。当负载均衡服务器接受到请求之后,通过改写报文的目标MAC地址的方式将请求转发到目标机器实现负载均衡。

三层:网络层,该层在数据传输时根据IP地址定位到唯一的机器,在该层中负载均衡服务器依旧对外提供一个VIP(虚IP),但是集群中不同的机器采用不同的IP地址。当负载均衡服务器接受到请求之后,根据不同的负载均衡算法,通过IP将请求转发至不同的真实服务器。

四层:传输层,该层通过IP+端口定位到唯一应用,通过修改数据报文中的IP,将请求转发给被负载均衡的服务器。主要是基于tcp协议报文,可以做任何基于tcp/ip协议的软件的负载均衡,比如Haproxy、LVS等。

七层:应用层,七层负载均衡基本都是基于http协议的,适用于web服务器的负载均衡,比如Nginx等。

2.1.4 DNS负载均衡

DNS,域名系统,处于第七层的最简单也是最常见的负载均衡方式,一般用来实现地理级别的均衡。例如北京、天津都访问北京的机房;上海、苏州都访问上海机房; 优点

  1. 简单、成本低:负载均衡工作交给DNS服务器处理,无须自己开发或者维护负载均衡设备。
  2. 就近访问,提升访问速度:DNS解析时可以根据请求来源IP,解析成距离用户最近的服务器地址,可以加快访问速度,改善性能。

缺点

  1. 更新不及时:DNS缓存的时间比较长,修改DNS配置后,由于缓存的原因,还是有很多用户会继续访问修改前的IP,这样的访问会失败,达不到负载均衡的目的,并且也影响用户正常使用业务。
  2. 扩展性差:DNS负载均衡的控制权在域名商那里,无法根据业务特点针对其做更多的定制化功能和扩展特性。
  3. 分配策略比较简单:DNS负载均衡支持的算法少;不能区分服务器的差异(不能根据系统与服务的状态来判断负载);也无法感知后端服务器的状态。

2.2 典型架构

了解完一些常见的负载均衡架构后,接下来看下负载均衡的典型实际应用。 当用户访问某个网站时,通过域名请求后端服务,经过DNS解析返回距离当前位置最近的服务器IP地址;

当用户访问服务器IP地址时,该请求会经过硬件负载均衡集群,由该集群将请求转发到四层负载均衡的LVS集群上;

LVS接收到请求后在根据已有的配置将请求转发到具体的七层负载均衡NGINX集群上;

最后由NGINX集群将请求转发到具体得应用集群,应用集群处理完毕后响应该客户端。

2.3 常用算法

负载均衡的算法有很多,如果按照算法被负载均衡机器的实时情况是否影响负载均衡来划分可以划分为静态负载均衡算法和动态负载均衡算法;

常见的静态均衡算法:轮询法、随机法、源地址哈希法、一致性哈希法、加权轮询法、加权随机法。

常见的动态负载均衡算法:最少连接数法、最快响应速度法。

  1. 轮询法 每一次来自网络的请求轮流分配给内部中的服务器,从1至N然后重新开始。此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。
  2. 随机法 将请求随机分配到各个节点。
  3. 源地址哈希法 根据请求源 IP,通过哈希计算得到一个数值,用该数值在候选服务器列表的进行取模运算,得到的结果便是选中的服务器。
  4. 一致性哈希法 一些场景希望同样的请求尽量落到一台机器上,比如访问缓存集群时,我们往往希望同一种请求能落到同一个后端上,以充分利用其上已有的缓存,不同的机器承载不同的稳定请求量(也可以理解为固定批用户的请求)。而不是随机地散落到所有机器上,那样的话会迫使所有机器缓存所有的内容,最终由于存不下形成颠簸而表现糟糕。 我们都知道hash能满足这个要求,比如当有n台服务器时,输入x总是会发送到第hash(x) % n台服务器上。但当服务器变为m台时,hash(x) % n和hash(x) % m很可能都不相等,这会使得几乎所有请求的发送目的地都发生变化,如果目的地是缓存服务,所有缓存将失效,继而对原本被缓存遮挡的数据库或计算服务造成请求风暴,触发雪崩。一致性哈希是一种特殊的哈希算法,在增加服务器时,发向每个老节点的请求中只会有一部分转向新节点,从而实现平滑的迁移。
  5. 加权轮询法 当集群内机器的配置不一致时,对于高带宽机器可以适当增加一些权重,增大被轮询的次数,从而分摊更多的流行,充分利用系统资源。
  6. 加权随机法 与加权轮询法本质一样,都是为了充分利用系统资源。
  7. 最少连接数法 将请求分发到连接数/请求数最少的候选服务器,已达到负载均衡的目的。客户端的每一次请求服务在服务器停留的时间可能会有较大的差异,随着工作时间加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生极大的不同,并没有达到真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录,记录当前该服务器正在处理的连接数量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况,负载更加均衡。此种均衡算法适合长时处理的请求服务,如FTP。
  8. 最快响应速度法根据请求的响应时间,来动态调整每个节点的权重,将响应速度快的服务节点分配更多的请求,响应速度慢的服务节点分配更少的请求。负载均衡设备对内部各服务器发出一个探测请求(例如Ping),然后根据内部中各服务器对探测请求的最快响应时间来决定哪一台服务器来响应客户端的服务请求。此种均衡算法能较好的反映服务器的当前运行状态,但这最快响应时间仅仅指的是负载均衡设备与服务器间的最快响应时间,而不是客户端与服务器间的最快响应时间。

三、单服务网络通信模型

单服务网络通信模型,是指描述单个应用在接受网络请求、处理、响应整个过程核心步骤的模型。

3.1 PPC

在计算机发展初期,用户群体没有那么大,当用户发送一个请求后,服务器就会新建一个进程去专门处理该请求,这是传统的UNIX网络服务器所采用的模型,请求与进程之间的关系是一对一,也就是Process Per Connection,缩写为PPC。

通信模型:

当应用起来后进行网络通讯的标准流程:创建socket,绑定端口号、监听网络请求、接受网络请求、处理用户请求、关闭通讯;

在PPC中处理用户请求这一步,当一个请求过来之后会fork一个子进程,由子进程对读取请求入参等信息,按照业务需求处理完毕后再将结果响应给客户端,最后关闭连接释放资源。

整体流程非常简单,也很好理解,使用起来也比较方便,但性能不高;创建进程操作系统需要申请大量CPU、IO等资源,此过程十分耗时,且系统的资源是一定的,这也注定该模型仅使用与小型应用。

改进 当用户请求过来后采取创建进程,而创建进程有十分耗时,性能不高;对该问题常见的优化思路就是使用”池化技术“,提前创建好进程池,当用户请求过来后,从进程池中获取一个进程处理用户请求,处理完毕后再归还进程到进程池中。

虽然一定程度上可以提高优化性能,进程比较消耗系统资源,庞大的进程仅处理一个请求,显然有点浪费资源;既然创建进程需要消耗大量系统资源,将进程替换成更轻量级的线程呢?似乎也可以跑的通,于是就衍生了新的通信模型:TPC

3.2 TPC

TPC(Thread Per Connection),每次有新的连接就新建一个线程去专门处理这个连接的请求。

通信模型:

运行流程、优点与PPC类似不在重复叙述。

缺点:

  1. TPC是PPC的另一种优化思路,线程虽然资源较少但不意味着不消耗资源,当千级别用户请求过来机器就无法响应了。
  2. 线程的引入势必引入线程常见的问题,如死锁,线程安全等。

改进

与PPC改进方式类似,也会引入”池化技术“优化频繁创建线程导致的性能问题。

都是一个请求对应一个处理模型,网络模型决定了上限,如果换一种方式:让多个请求由一个线程呢?接下来我们看下Reactor模型

3.3 Reactor

Reactor 是一个基于多路复用、由事件驱动的IO模型。多个用户请求事件由统一内容分发器接收,然后根据事件类型转发给对应的事件处理器,如下图所示:

关键词说明:

service handler: 通过封装selector(多路复用)接收用户的的请求,根据请求事件类型将请求转发给不同事件处理器。

request handler 事件处理器,用于处理用户的请求事件,完成用户的具体操作。

以上只是Reactor的模型,在实际实现上常见有三种方式:单线程reactor、多线程Reactor、主从Reactor;

3.3.1 单线程reactor

执行流程:

  1. 用户请求过来后,reactor通过select接收用户IO事件,收到事件后通过dispatch进行转发。
  2. 如果事件是建立连接事件,调用acceptor建立网络连接,然后创建handler对象实例执行后续流程。
  3. 如果事件是不建立连接事件,将请求转发到网络连接对应的handler进行处理。
  4. handler处理请求的过程是read(读取网络数据) -> 业务处理 -> send(将处理结果响应给客户端)

注:图中的hander1、hander2表示handler实例对象,而不是不同的handler,这里只是想表达handler有很多个实例。

优点:相对简单;缺点则是无法充分发挥多核CPU优势;当一个业务处理阻塞则直接影响整个服务。

3.3.2 多线程reactor

执行流程:

  1. 用户请求过来后,reactor通过select接收用户IO事件,收到事件后通过dispatch进行转发。
  2. 如果事件是建立连接事件,调用acceptor建立网络连接,然后创建handler对象实例执行后续流程。
  3. 如果事件是不建立连接事件,将请求转发到网络连接对应的handler进行处理。
  4. handler处理请求的过程是read(读取网络数据) -> 业务处理 -> send(将处理结果响应给客户端)。其中在业务处理这一步会直接将请求交给业务线程池。

说明: 与单线程Reactor相比,将业务处理部分通过多线程的方式进行处理,可以充分发挥多核CPU的性能,也一定程度上缓解了一个业务流程执行慢从而影响整个服务的问题。

多线程reactor只是将业务处理部分使用多线程进行优化,当用户请求比较多时,一个线程需要与用户建立网络连接、读取用户请求、响应结果,尤其读取、响应属于高IO操作的,IO本身十分消耗性能,使得这里容易成为系统瓶颈,为此还需要再次优化。

3.3.3 主从线程reactor

相对于多线程Reactor,将原Reactor功能拆分成主从两个Reactor,其中主Reactor仅负责网络连接、身份认证、IP黑白名单过滤等;读取网络请求、响应处理结果这种高IO交给从reactor池处理,一般来说从Reactor数量与CPU核心数量保持一致,不同业务可能有所不同。 执行流程:

  1. 用户请求过来后,主reactor通过select接收用户IO事件,收到事件后通过dispatch进行转发。
  2. 如果事件是建立连接事件,调用acceptor建立网络连接,然后将建立好的网络连接交给从Reactor,然后从Reactor创建handler对象实例执行后续流程。
  3. 如果事件是不建立连接事件,将请求转发给子Reactor。
  4. 子reactor通过selector监听到用户的请求事件后,将请求转发到网络连接对应的handler进行处理。
  5. handler处理请求的过程是read(读取网络数据) -> 业务处理 -> send(将处理结果响应给客户端)。其中在业务处理这一步会直接将请求交给业务线程池。

3.3.4 总结

Reactor是一个多路复用的简单、高性能、扩展性好的同步非阻塞IO模型,主要体现在:

  1. 同步非阻塞:读取IO、响应是同步的,建立网络连接、处理业务请求是非阻塞的。
  2. 简单:模型整体简单易理解,实现上也不复杂,无需过多处理多线程及同步问题。
  3. 高性能:单机可以支持很高的用户请求。
  4. 高扩展性:可以方便地通过增加Reactor实例个数来充分利用CPU资源;事件处理与Reactor模型分开,事件的变化不会影响Reactor本身,新增、修改事件只需增加类型和处理类即可,很容易扩展;

3.4 Proactor

Proactor 异步、非阻塞的IO模型,理论上Proactor比Reactor效率要高一些,但目前业界并没有成熟的实现,导致知名度较低。

Reactor可以理解为“来了事件我通知你,你来处理”,而Proactor可以理解为“来了事件我来处理,处理完了我通知你”。这里的“我”就是操作系统内核,“事件”就是有新连接、有数据可读、有数据可写的这些I/O事件,“你”就是我们的程序代码。

执行流程:

  1. Proactor Initiator负责创建Proactor和Handler,并将Proactor和Handler都通过Asynchronous Operation Processor注册到内核。
  2. Asynchronous Operation Processor负责处理注册请求,并完成I/O操作。
  3. Asynchronous Operation Processor完成I/O操作后通知Proactor。
  4. Proactor根据不同的事件类型回调不同的Handler进行业务处理。
  5. Handler完成业务处理,Handler也可以注册新的Handler到内核进程。

四、架构设计业界著名理论

4.1 CAP理论

理论内容: 在一个分布式系统(指互相连接并共享数据的节点的集合)中,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲,这里的牺牲并不是指完全放弃,只是无法做到100%而已!

一致性(Consistency): 对于上游客户端来说,每次查询的数据都可以返回最新操作的写结果。

可用性(Availability):正常节点在合理的时间内均可以返回正确的结果,正确的结果不包含熔断、超时等异常响应。

分区容忍性(Partition Tolerance):分布式系统出现网络分区的时候,仍然能够对外提供服务。这里的网路分区是指分布式系统中,多个节点之前的网络本来是连通的,但是因为某些故障(比如部分节点网络出了问题)某些节点之间不连通了,整个网络就分成了几块区域,这就叫网络分区。

应用

在实际的分布式应用中,网络不可能做到100%可靠,因此P是必须保留的,也就是我们只能在AP、CP中作选择。我们常用的Zookeeper 是CP架构,Eureka是AP架构。

关键细节点

  1. CAP关注的粒度是数据,而不是整个系统;一个系统包含的模块、数据有很多,不同的模块、数据对CAP的要求是不一样的,例如下单时计算订单金额要求CP,订单列表则要求AP;
  2. CAP是忽略网络延迟的;在分布式系统中,无论采用什么架构,数据的同步都一定存在,那怕是几毫秒。对于一些场景几毫米延迟都是无法容忍的,因此一些场景可能会采取CA架构,例如热门商品的库存。
  3. 正常运行情况下,不存在CP和AP的选择,可以同时满足CA。
  4. CAP理论中的放弃并不等于什么都不做,只是无法做到100%,仍需要为被放弃的一项做努力。

4.2 BASE理论

BASE是指基本可用BA(Basically Available)、软状态S( Soft State)、最终一致性E( Eventual Consistency)的简写,本质上是对CAP的延伸和补充,是对CAP中的AP方案的一个补充,即在选择AP方案的情况下,如何更好地最终达到C。

基本可用(Basically Available):分布式系统在出现故障时,允许损失部分可用性,保证核心可用。例如当服务器压力过大,对部分非核心功能进行降级。

软状态(Soft State):允许系统存在中间状态,而该中间状态不会影响系统整体可用性。这里的中间状态就是CAP理论中的数据不一致。例如允许分区之间有同步延迟。

最终一致性(Eventual Consistency):系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。

五、FMEA方法

失效模式与影响分析(英文:Failure mode and effects analysis,FMEA),又称为失效模式与后果分析、失效模式与效应分析、故障模式与后果分析或故障模式与效应分析等,是一种操作规程,旨在对系统范围内潜在的失效模式加以分析,以便按照严重程度加以分类,或者确定失效对于该系统的影响。--来自维基百科

作用: 计算出故障严重程度值,以严重程度优先级别最高的失效着手,采取行动措施,从而消除或减少故障;

内容: 按照分析表列出有哪些功能点、这些功能点可能发生的故障有哪些、故障的影响范围、发生概率等,根据验证程度思考应对方案,从而优化我们的架构。

具体分析项:

  1. 功能点: 站在用户角度分析有哪些功能点。
  2. 故障: 指的是系统会出现什么样的故障,包括故障点和故障形式,例如搜索速度很慢,三四秒才返回搜索结果。一个故障可能原因很多,可以按照故障*原因穷举所有结果。注意故障的描述要尽量精确,多使用量化描述(不需要准确,粗估即可),避免使用泛化的描述。例如,推荐使用“MySQL响应时间达到3秒”,而不是“MySQL响应慢”。
  3. 故障影响: 当发生故障时对用户的影响是什么,例如功能完全不可用,部分用户可用,少量用户不可用;注意影响范围尽量也描述使用量化描述(不需要准确,粗估即可),例如,50%用户不可用
  4. 严重程度: 严重程度指站在业务的角度故障的影响程度,一般分为“致命/高/中/低/无”五个档次。严重程度按照这个公式进行评估:严重程度 = 功能点重要程度 × 故障影响范围 × 功能点受损程度。当出现敲不定严重程度时,让leader拍板就行,不要在此浪费过多时间。
  5. 故障原因: 在”故障“描述了故障时怎么样的,但原因不同,例如搜索很慢可能是带宽被占满,也可能是性能问题,不同原因解决方案不同。
  6. 故障概率: 基于”故障原因“定出该原因出现概率,分为高中低就行。
  7. 风险程度: 将故障的严重程度和发生概率相结合,计算出风险程度,为后续应对做准备;风险程度=严重程度*发生概率
  8. 已有措施: 基于风险程度、原因系统是否已经作出了相应的处理措施。
  9. 规避措施: 减少或消除该风险要做的事情,不限于技术。例如为了提高数据库可用型,购买云厂商的服务。
  10. 解决措施: 风险的应对方案,一般都是技术要做的事情;为了提供可用性,将单机换成主从架构。
  11. 后续规划: 风险过多无法一次完成,可以分阶段完成;风险解决方案需要消耗很长时间,一次性解决成本过大,分期迭代来完成。

案例 假设某电商平台需要实现一个下单和列表查询功能;当下单后需要扣除库存,为了放到数据库被大流量打垮,将库存放到缓存中,异步写入数据库中;列表查询直接查询数据库即可。

功能点 故障 故障影响 严重程度 故障原因 故障概率 风险程度 已有措施 规避措施 解决措施 后续规划
下单 服务器无法访问 全部用户 致命 设备故障 定期巡检设备,临期设备及时更换 采用集群,一台故障还有其他集群顶替
下单 MYSQL响应超过3秒 10%的用户 宽带被占满 增加宽带使用监控,当超过某个值时及时告警,到红线值自动扩容;大促时期提前扩容 增加带宽
下单 MYSQL响应超过3秒 10%的用户 慢SQL 慢SQL检测,及时告警 杀死慢SQL执行请求
下单 数据库与缓存超过1个小时库存不一致 BUG 编写脚本对比数据库与缓存差异 解决BUG
订单列表 MYSQL响应超过3秒 10%的用户 慢SQL 慢SQL检测,及时告警 杀死慢SQL执行请求

经过以上表格分析,我们需要做的一些改进:

  1. 数据库、Redis、服务都需要集群架构;
  2. 完善数据库运维,增加数据库慢SQL监控;

于是我们得出最终的架构:

FMEA是高可用架构设计的一个非常有用的方法,不仅能够发现架构中隐藏的高可用问题,在项目管理过程中也有类似方案,感兴趣的可以自行搜索。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章