常见容错机制:failover、failfast、failback、failsafe
failover:失效转移 当主要组件异常时,其功能转移到备份组件。
failfast:快速失败(不持续等待)
failback:失效自动恢复
failsafe:失效安全 即使在故障的情况下也不会造成伤害或者尽量减少伤害
- 一些熔断组件会实现这些功能
服务降级怎么做
cloud.tencent.com/developer/a…
保证核心服务可用;非核心服务弱可用,甚至不可用
- 核心服务:直接和钱沾边,或者间接和钱沾边
- 购物车、支付 等
- 非核心服务:和钱不沾边,或者不影响支付
-
我的订单、退货服务 等
-
服务降级手段
拒绝部分请求(限流)
关闭部分业务(业务相关)
服务层降级架构层次
-
集中式
- 网关层
-
自治式
- 业务逻辑层
- 数据访问层 因为不同的层次的同样设备的处理能力是不一样的,假设网关层能处理200请求,业务逻辑层只能处理100请求,数据访问层,只能处理50请求
集中式:
直接在网关层砍掉150请求才能符合数据访问层的请求能力,并且是中间隔着业务逻辑层的,并不好知道
自治式:
层层降级,最终砍到数据访问层能处理的请求数量,因为每层都是挨着的所以,容易一些
数据层降级
-
更新请求
- 持久到消息队列
- 只更新缓存
-
读请求
- 读缓存
-
数据补齐
- 消息队列->[数据库]
新浪微博,在数据流量的高峰期,比如网红发段子,或者一些事件,那么更新的消息数据会写到队列中并写入缓存,其他人拉取的时候,都是读取的缓存,等到流量陷入低峰期时,读取消息队列,并写入到数据库,实现数据补齐
限流、熔断
服务雪崩
当 “服务C” 出现问题时,可能是宕机,上线出 bug,流量过大或缓存穿透数据库压垮服务,这时“服务 C”响应就会出问题,而“服务 B”由于拿不到响应结果又会不断重试进一步压垮“服务 C”,同时“服务 B”同步调用也会有大量等待线程,出现资源耗尽,导致“服务 B”变得不可用,进而影响到“服务 A”,形成雪崩效应。
上游服务做限流,下游服务做熔断
限流算法
zhuanlan.zhihu.com/p/376564740
固定窗口限流算法
首先维护一个计数器,将单位时间段当做一个窗口,计数器记录这个窗口接收请求的次数。
- 当次数少于限流阀值,就允许访问,并且计数器+1
- 当次数大于限流阀值,就拒绝访问。
- 当前的时间窗口过去之后,计数器清零。 伪代码如下:
boolean fixedWindowsTryAcquire() {
long currentTime = System.currentTimeMillis(); //获取系统当前时间
if (currentTime - lastRequestTime > windowUnit) { //检查是否在时间窗口内
counter = 0; // 计数器清0
lastRequestTime = currentTime; //开启新的时间窗口
}
if (counter < threshold) { // 小于阀值
counter++; //计数器加1
return true;
}
return false;
}
有临界问题
滑动窗口限流算法
滑动窗口限流解决固定窗口临界值的问题。它将单位时间周期分为n个小周期,分别记录每个小周期内接口的访问次数,并且根据时间滑动删除过期的小周期。
并没有真正解决临界突发流量问题。 一旦到达限流后,请求都会被暴力拒绝。
漏桶算法
1.容量限制:漏桶有一个固定的容量,一旦达到容量,进入的额外数据会被丢弃 2.恒定流出速率:数据以固定的速率从桶中流出。 3.流入速率可变:数据可以以任意速率流入桶内。
令牌桶算法
- 系统根据限流大小,定速往令牌桶里放令牌。
- 如果令牌数量满了,超过令牌桶容量的限制,那就丢弃。
- 系统在接受到一个用户请求时,都会先去令牌桶要一个令牌。如果拿到令牌,那么就处理这个请求的业务逻辑;
- 如果拿不到令牌,就直接拒绝这个请求。
这种算法允许的最大并发请求量就是令牌桶的容量
熔断
zhuanlan.zhihu.com/p/340660145
熔断器设计模式是基于 AOP 对所有的请求调用进行拦截,在请求调用前做状态判断是否熔断,请求调用后做计数统计 (记录失败比例),并根据策略做熔断状态转移。
框架
sentinel-golang