11---
2- title : 高可用系统设计详解:SLA、限流、熔断、降级、冗余、灰度发布和故障恢复
3- description : 高可用系统设计指南,讲解 SLA 和多少个 9、常见故障原因、 单点故障治理,以及限流、熔断、降级、缓存、异步、冗余、灰度发布等提升系统可用性的方案 。
2+ title : 高可用系统设计详解:SLA、限流熔断、降级容灾、缓存与灰度发布
3+ description : 高可用系统设计指南,讲解 SLA 和多少个 9、单点故障治理、限流熔断、服务降级、缓存高可用、异步削峰、冗余容灾、灰度发布和故障恢复等核心方案 。
44category : 高可用
55icon : " mdi:palette-swatch-outline"
6+ tag :
7+ - 高可用
8+ - 系统设计
69head :
710 - - meta
811 - name : keywords
9- content : 高可用,高可用系统设计,系统可用性 ,SLA,多少个9 ,单点故障,限流,熔断,降级,冗余设计 ,灰度发布,故障恢复,高可用架构 ,系统稳定性
12+ content : 高可用,高可用系统设计,高可用架构 ,SLA,多少个 9 ,单点故障,限流熔断,服务降级,缓存高可用,冗余容灾 ,灰度发布,故障恢复,系统稳定性
1013---
1114
1215## 什么是高可用?可用性的判断标准是啥?
1316
14- ** 高可用(High Availability,简称 HA)** 描述的是一个系统在大部分时间都是可用的,可以为我们提供服务的 。高可用代表系统即使在发生硬件故障或者系统升级的时候,服务仍然是可用的。
17+ ** 高可用(High Availability,简称 HA)** 是指系统在绝大部分时间内能够持续提供正常服务的能力 。高可用代表系统即使在发生硬件故障或者系统升级的时候,服务仍然是可用的。
1518
16- 一般情况下,我们使用 ** 多少个 9** 来评判一个系统的可用性,比如 99.9999% 就是代表该系统在所有的运行时间中只有 0.0001% 的时间是不可用的,这样的系统就是非常非常高可用的了!当然,也会有系统如果可用性不太好的话,可能连 9 都上不了 。
19+ 一般情况下,我们使用 ** 多少个 9** 来评判一个系统的可用性,比如 99.9999% 就是代表该系统在所有的运行时间中只有 0.0001% 的时间是不可用的,这样的系统就是非常非常高可用的了!可用性较差的系统可能连 90%(1 个 9)都达不到 。
1720
1821| 可用性等级 | 可用性百分比 | 年度停机时间 | 典型场景 |
1922| ---------- | ------------ | ------------ | ------------ |
@@ -113,24 +116,24 @@ flowchart TB
113116
114117如何提高代码质量?比较实际可用的就是 ** Code Review** ,不要在乎每天多花的那 1 个小时左右的时间,作用可大着呢!
115118
116- 另外,安利几个对提高代码质量有实际效果的工具 :
119+ 另外,推荐几个对提高代码质量有实际效果的工具 :
117120
118- - [ Sonarqube ] ( https://www.sonarqube.org/ ) :静态代码分析平台,可检测代码坏味道、安全漏洞和 Bug。
121+ - [ SonarQube ] ( https://www.sonarqube.org/ ) :静态代码分析平台,可检测代码坏味道、安全漏洞和 Bug。
119122- Alibaba 开源的 Java 诊断工具 [ Arthas] ( https://arthas.aliyun.com/doc/ ) :可在线排查 JVM 问题,支持热更新代码。
120123- [ 阿里巴巴 Java 代码规范] ( https://github.com/alibaba/p3c ) (Alibaba Java Code Guidelines):配套 IDEA 插件,实时检查代码规范。
121124- IDEA 自带的代码分析等工具。
122125
123126### 使用集群,减少单点故障
124127
125- ** 单点故障(Single Point of Failure,SPOF)** 是高可用的大敌。先拿常用的 Redis 举个例子!我们如何保证我们的 Redis 缓存高可用呢?答案就是使用集群,避免单点故障 。
128+ ** 单点故障(Single Point of Failure,SPOF)** 是高可用的大敌。以 Redis 缓存为例:使用集群模式避免单点故障,是保障其高可用的关键手段 。
126129
127- 当我们使用一个 Redis 实例作为缓存的时候,这个 Redis 实例挂了之后,整个缓存服务可能就挂了。使用了集群之后 ,即使一台 Redis 实例挂了,不到一秒就会有另外一台 Redis 实例顶上 。
130+ 当我们使用一个 Redis 实例作为缓存的时候,该 Redis 实例宕机后,整个缓存服务就可能不可用。使用集群之后 ,即使一台 Redis 实例宕机,也可以通过故障转移让其他实例接管。切换时间取决于部署模式和参数配置, Redis Sentinel/Cluster 通常需要数秒到数十秒,不应简单理解为“不到一秒” 。
128131
129132常见的集群模式:
130133
131134- ** 主从复制(Master-Slave)** :一主多从,主节点负责写,从节点负责读,主节点故障时需要手动或借助哨兵进行故障转移。
132135- ** 哨兵模式(Sentinel)** :在主从复制基础上增加哨兵节点,实现自动故障检测和转移。
133- - ** 分布式集群( Cluster) ** :数据分片存储在多个节点 ,每个分片有主从副本,兼顾高可用和水平扩展。
136+ - ** Redis Cluster 模式 ** :Redis 3.0+ 官方支持的数据分片方案 ,每个分片有主从副本,兼顾高可用和水平扩展。
134137
135138### 限流
136139
@@ -151,17 +154,19 @@ flowchart TB
151154
152155** 重试的次数一般设为 3 次** ,再多次的重试没有好处,反而会加重服务器压力(部分场景使用失败重试机制会不太适合)。同时,重试需要配合 ** 指数退避** 策略,避免重试风暴。
153156
157+ 需要特别注意的是,重试的接口必须具备幂等性。对于创建订单、资金扣减这类非幂等写操作,应通过唯一请求 ID、业务唯一键、状态机等方式防止重复执行,而不是简单地把失败请求再发一遍。读操作可以相对积极地重试,写操作重试前最好先查询上一次请求是否已经生效。
158+
154159### 熔断机制
155160
156- 超时和重试机制设置之外,** 熔断机制** 也是很重要的。熔断机制说的是系统自动收集所依赖服务的资源使用情况和性能指标,当所依赖的服务恶化或者调用失败次数达到某个阈值的时候就迅速失败,让当前系统立即切换依赖其他备用服务 。
161+ 超时和重试机制设置之外,** 熔断机制** 也是很重要的。熔断机制说的是系统自动收集所依赖服务的资源使用情况和性能指标,当所依赖的服务恶化或者调用失败次数达到某个阈值时,熔断器进入 Open 状态,后续请求直接快速失败,不再调用下游服务,避免故障继续扩散。熔断通常会配合降级策略使用,比如返回兜底数据或调用备用服务 。
157162
158163熔断器有三种状态:
159164
160165- ** 关闭(Closed)** :正常状态,请求正常通过。
161166- ** 打开(Open)** :熔断状态,请求直接失败,不调用下游服务。
162167- ** 半开(Half-Open)** :尝试恢复状态,放行少量请求探测下游服务是否恢复。
163168
164- 比较常用的流量控制和熔断降级框架是 Netflix 的 Hystrix 和 alibaba 的 Sentinel。
169+ 历史上广泛使用的流量控制和熔断降级框架有 Netflix Hystrix(已进入维护模式)和 Alibaba Sentinel。新项目通常更推荐使用 Sentinel 或 Resilience4j 。
165170
166171### 降级
167172
@@ -175,22 +180,28 @@ flowchart TB
175180
176181### 异步调用
177182
178- 异步调用的话我们不需要关心最后的结果,这样我们就可以用户请求完成之后就立即返回结果,具体处理我们可以后续再做 ,秒杀场景用这个还是蛮多的。
183+ 异步调用是指调用方发起请求后不阻塞等待处理结果,而是立即返回,具体处理可以后续再做 ,秒杀场景用这个还是蛮多的。
179184
180185但是,使用异步之后我们可能需要 ** 适当修改业务流程进行配合** ,比如 ** 用户在提交订单之后,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功** 。
181186
182187除了可以在程序中实现异步之外,我们常常还使用 ** 消息队列** ,消息队列可以通过异步处理提高系统性能(削峰、减少响应所需时间)并且可以降低系统耦合性。
183188
184189### 使用缓存
185190
186- 如果我们的系统属于并发量比较高的话,如果我们单纯使用数据库的话,当大量请求直接落到数据库可能数据库就会直接挂掉 。使用缓存缓存热点数据,因为缓存存储在内存中,所以速度相当地快!
191+ 在高并发场景下,如果所有请求都直接打到数据库,数据库很可能因压力过大而崩溃 。使用缓存缓存热点数据,因为缓存存储在内存中,所以速度相当地快!
187192
188193缓存的典型应用场景:
189194
190195- ** 热点数据缓存** :将访问频繁的数据放入 Redis 等缓存中。
191196- ** 页面缓存** :将渲染后的页面缓存起来,减少服务器压力。
192197- ** 本地缓存** :使用 Caffeine、Guava Cache 等本地缓存,减少网络开销。
193198
199+ 缓存本身也要考虑高可用下的典型故障模式:
200+
201+ - ** 缓存穿透** :查询不存在的数据,请求全部穿透到数据库。常见应对方式有参数校验、空值缓存、布隆过滤器。
202+ - ** 缓存击穿** :热点 Key 过期瞬间,大量请求同时打到数据库。常见应对方式有互斥锁、逻辑过期、热点 Key 永不过期 + 异步刷新。
203+ - ** 缓存雪崩** :大量 Key 同时过期或缓存集群不可用。常见应对方式有过期时间加随机偏移、多级缓存、缓存集群高可用。
204+
194205### 其他
195206
196207- ** 核心应用和服务优先使用更好的硬件** :核心服务使用更高配置的服务器、SSD 硬盘等。
0 commit comments