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