# 面试题:如果你是架构师,如何保证系统的可用性? 这是一个极硬核的系统设计题,通常出现在 **高级工程师 / 技术经理 / 架构师** 的面试中。 背景是:现代互联网系统需要在 **高并发、瞬时流量、偶发故障、节点宕机、依赖不稳** 的情况下保持稳定运行。 可用性(Availability)不仅取决于代码质量,更取决于整体架构设计、降级策略、弹性能力、监控体系、混沌工程等综合手段。 **问题核心:** 1. **冗余(Redundancy):** 系统挂一台不影响整体。 2. **隔离(Isolation):** 局部失败不能扩散,不能“牵一发而动全身”。 3. **降级(Degrade):** 在资源不足时优雅地“牺牲部分功能”,避免整体雪崩。 4. **流量与负载控制(Traffic & Load):** 流量不能把系统冲垮。 5. **观测(Observability):** 有问题必须能快速发现、定位、恢复。 下面给出我作为架构师会采用的“多层可用性体系设计”,分层、分级、明确目的,就像真正设计一个高可用系统一样。 --- ## 方案一:多副本 + 自动故障切换(高可用的基础设施层) 无论是数据库、缓存、微服务,都必须具备至少两点: ### 1.1 服务多副本(N+1 架构) * 应用服务:多副本、无状态,可随时扩容缩容 * Redis:主从 + 哨兵 * MySQL:主从复制 + 自动主备切换 * Kafka:多副本,ISR机制 * Kubernetes:Deployment + HPA + LivenessProbe **核心目标:** 单机故障不影响服务。 --- ### 1.2 自动故障切换(Failover) 服务健康检查失败自动摘除;数据库、缓存的主节点挂掉自动切主。 **核心目标:** 故障恢复不依赖人工。 --- ## 方案二:限流 + 熔断 + 隔离(避免雪崩的利器) 这是高可用架构的灵魂,负责应对**流量激增、下游不稳、请求堆积**。 ## 2.1 限流(流量不能无限进入系统) * 令牌桶 * 漏桶 * Nginx ingress 限速 * API Gateway 限流 * Redis 分布式限流 目的:**保护核心资源不被打爆**。 --- ### 2.2 熔断(下游挂了立即阻断) 典型如 Hystrix / Sentinel: * 调用超时 → 熔断 * 失败率过高 → 熔断 * 下游不可达 → 熔断 熔断后返回 fallback(例如“稍后再试”)。 目的:**阻止抖动的下游拖垮整个调用链**。 --- ### 2.3 资源隔离(线程池隔离/舱壁模式) * 搜索线程池 * 支付线程池 * 推荐线程池 互相隔离,做到: **“一个模块出问题,只影响自己,不影响别人”** --- ## 方案三:功能降级体系(在极限场景下牺牲部分功能以保整体可用) 这部分是架构师的成熟标志。 ### 降级策略包括: * 数据不实时改为读取缓存 * 推荐模块不可用时返回热门榜单 * 发短信失败改成重试队列 * 订单详情部分字段使用兜底数据 * 评论系统只读不写 * 秒杀系统进入排队模式 目标只有一个: **在极端情况下保证核心路径可用,比如下单、支付、登录。** --- ## 方案四:异步化 + 削峰填谷(应对瞬时高流量) 采用: * Kafka / RocketMQ 进行削峰 * 订单、支付、库存采用 MQ 异步处理 * 任务用队列或延时队列缓冲 * 大型任务拆分为批处理 目的: **把瞬时峰值变成系统可承受的平均值。** --- ## 方案五:缓存体系(高可用的性能基础) 使用: * Redis 多副本 + 持久化 * 本地缓存(go-cache、Guava) * 缓存穿透、击穿、雪崩防护 * 分布式锁保证缓存重建顺序 核心目标: **提升读性能的同时保护数据库。** --- ## 方案六:灰度发布 + 蓝绿发布 + 自动回滚(保证上线可用性) 上线是事故最高发阶段。 作为架构师一定要推行: * 灰度发布:按用户/地域/比例逐步放量 * 蓝绿发布:两套环境切换 * 自动回滚:探测到错误立即回滚 * Canary 发布:先导流小流量,看指标再放量 目标: **让“上线”从风险点变成可控动作。** --- ## 方案七:监控 + 告警 + 日志 + 链路追踪(Observability) 没有观测,就没有高可用。 监控系统包括: * Metrics(Prometheus/Grafana) * 日志平台(ELK / Loki) * 链路追踪(Jaeger / SkyWalking) * 告警平台(SRE oncall) * SLA / SLO 指标(错误率、TP99) 目标: **尽早发现问题 + 准确定位 + 快速恢复。** --- # 方案八:混沌工程(Chaos Engineering) 当系统足够成熟,需要构造真实故障来验证高可用能力。 例如: * 随机宕掉服务 * 注入网络延迟 * 注入磁盘满 * 注入下游不可用 * 注入超时场景 目的: **提前暴露脆弱点,让架构在真实故障面前更稳定。** --- # 面试总结话术 你可以这样回答: > “作为架构师,我会把系统可用性拆成八个层面来设计。 > > **第一是在基础设施做冗余和自动故障切换,保证单点故障不会影响系统。** > **第二是通过限流、熔断、隔离来保证系统不被下游或突发流量拖垮。** > **第三是构建完整的降级体系:核心功能优先保证,下游不稳也能 fallback。** > **第四是利用 MQ 进行异步化和削峰填谷,防止瞬时流量压穿数据库。** > **第五是缓存体系优化,配合本地缓存和 Redis 防护确保读性能与稳定性。** > **第六是发布流程的高可用:灰度、蓝绿、自动回滚降低上线风险。** > **第七是完善的监控、告警和链路追踪,让问题能够被快速发现和定位。** > **第八是混沌工程,通过主动造故障验证高可用能力。** > > 这套“冗余 + 限流 + 降级 + 异步 + 缓存 + 发布控制 + 监控 + 混沌工程”的体系,能确保系统在高并发、故障、突发流量下依然保持高可用。”