大型互联网系统架构设计,无法避免的四类问题,高可用、高性能、高并发、高扩展。
高可用的设计技巧
1、系统拆分
2、解耦
3、异步
4、重试
5、补偿
6、备份
7、多活策略
8、隔离
9、限流
10、熔断
11、降级
一 系统拆分
面对一个又大又复杂的系统,防止一个功能出问题,导致整个系统的不能使用。我们需要对整个系统按功能拆分成一个一个的小模块,这样就可以防止一个小功能出问题,导致整个系统不能使用。对应的有微服务架构和ddd架构。
二 解耦
软件开发的其中一个重要原则就是"高内聚,低耦合"。当很多子系统都在调用其中某一个系统,这时候为了,后边方便维护。不至于每增加一个功能,都要这对这个子系统进行修改,便引用消息中间件。这就是为了解耦,当有的系统需要某个功能的数据,它只需要访问mq就可以,而不是直接访问功能模块。
三 异步
先介绍同步对比异步。同步是指在执行一个任务的时候,需要其他环节参与才能完成。例如,购买商品时候,你需要先将你买的商品信息存到数据库,然后生成一张订单表,然后库存减一,最后付款。如果是同步,那么那会按顺序执行,只有本环节执行完毕,才会执行下面的环节。这样就会导致响应时间太长,用户体验不友好。而且容易忘了等原因导致整个过程失败,这时候我们采用异步,当数据落库成功之后,我们执行下面的操作,不需要等待。直接下面操作各自运行就可以了。
我们可以采用消息队列的发布/订阅机制,数据库插入下单记录成功后,发布一条消息到mq,然后就可以告知用户下单成功了。彼此之间互不干扰。
四 重试
重试主要用在远程的RPC调用,受网络抖动,线程资源阻塞等因素,导致请求失败,为了提升用户体验等原因,我们可以再次发送请求。
重试通常和幂等组合使用,如果一个接口支持幂等,那你就可以随便重试。
幂等的解决方案:
插入前先执行查询操作,看是否存在,再决定是否插入
增加唯一索引
建防重表
引入状态机,比如付款后,订单状态调整为已付款,sql更新记录前增加条件判断
增加分布式锁
采用token机制,服务端增加token校验,只有一次请求是合法的
五 补偿
不是所有的请求都能得到成功响应的。除了重试,我们还可以用补偿,实现数据的最终一致性。
业务补偿根据处理的方向分为两部分
正向:多个操作构成一个分布式事务,如果部分成功、部分失败,我们会通过最大努力机制将失败的任务推进到成功状态。
逆向:道理同上,我们也可以采用反向操作,将部分成功任务恢复到初始状态。
注意:补偿有一个重要前提,业务能接受短时间的数据不一致。
补偿的实现方式
1、本地建表方式,存储相关数据,然后通过定时任务扫描提取,并借助反射机制出发执行
2、也可以采用简单的消息中间件,构建业务消息体,由下游的消费任务执行。如果失败,可以借助MQ的重试机制,多次重试。
六 备份
任何服务器都有宕机的可能性,一旦存储了数据,带上状态,如果发生故障,数据丢失,后果非常严重。
所以,容灾备份:也就成了互联网的基本能力,
一旦主节点挂了怎么办
这里引入哨兵机制。哨兵机制可以实现主从库的自动切换,有效解决了故障转移。整个过程分为三个阶段:监控、选主、通知。
七 多活策略
虽然有了备份策略,但仍然可能会有极端情况导致问题,例如机房断电,机房火灾、地震、山洪等不可抗因素,所有的服务器都有可能出现故障,导致无法对外提供服务。
常见的多活方案有,同城双活、两地三中心、三地五中心、异地双活、异地多活。
八 隔离
物理层面的隔离,将若干的系统低耦合设计,独立部署,从物理上隔开。将一个大型的复杂系统拆分成若干微服务系统,这些微服务子系统通常由不同的团队开发、维护、独立部署,服务之间通过RPC远程调用。
九 限流
高并发系统,如果遇到流量洪峰,超过了当前系统的承载能力。我们这时候需要有舍有得,多余的流量直接丢弃。
限流定义
限制到达系统的并发请求数量,保证系统能够正常响应部分用户请求,而对于超过限制的流量,则通过拒绝服务的方式保证系统的可用性。
限流分类
根据作用范围:限流分为单机版限流、分布式限流
单机限流
主要借助本机内存来实现计数器,比如通过AtomicLong的incrementAndGet(),但是注意之前不用的key定期做清理,释放内存。
纯内存实现,无需和其他节点统计汇总,性能最高。但是无法做到全局统一化的限流。
分布式限流
分布式限流以集群为维度,可以方便的控制这个集群的请求限制,从而保护下游依赖的各种服务资源。
限流支持多个维度
整个系统一定时间内(例如每分钟)处理多少个请求
单个接口一定时间内处理多少流量
单个IP、城市、渠道、设备id、用户id等在一定时间内发送的请求数
如果是开放平台,则为每个appkey设置独立的访问速率规则。
常见的限流算法
- 计数器限流
- 滑动窗口限流
- 漏桶限流
- 令牌桶限流
十 熔断
就是当某一个子服务出现问题,断路器会阻断对故障服务器的调用
断路器的三种状态:关闭、打开、半打开
状态机
1、关闭状态:在这个状态下,请求会被转发给后端服务。同时记录失败次数,当请求次数在一段时间超过一定次数就会进入打开状态。 2、打开状态:在这个状态下,熔断器会尝试把部分请求转发给后端服务,目的是为了探测后端服务是否恢复。如果请求失败会进入打开状态,成功情况下会进入关闭状态,同时重置计数。
十一 降级
为了有效资源发挥最大价值,我们会临时关闭一些非核心功能,减轻系统压力,把资源留给核心业务。
比如电商促销,业务在峰值时刻,系统抵挡不住全部的流量时,系统的负载,CPU的使用率都超过了预警水位,可以对一些非核心功能进行降级,比如把商品评价、成交记录等功能临时关掉。当然不同的公司,不同业务,处理的方式不同。需要结合实际场景分析。