系统高可用的 10 条军规

关系型数据库NoSQL数据库微服务

大家好,我是苏三,又跟大家见面了。

前言

系统高可用是非常经典的问题,无论在面试,还是实际工作中,都经常会遇到。

这篇文章跟大家一起聊聊,保证系统高可用的10条军规,希望对你会有所帮助。

picture.image

1 冗余部署

场景 :某电商大促期间,数据库主节点突然宕机,导致全站交易瘫痪。

问题 :单节点部署的系统,一旦关键组件(如数据库、消息队列)故障,业务直接归零。

解决方案 :通过主从复制、集群化部署实现冗余。例如MySQL主从同步,Redis Sentinel哨兵机制。

picture.image

MySQL主从配置如下:


        
          
-- 主库配置  
CHANGE MASTER TO   
MASTER_HOST='master\_host',  
MASTER_USER='replica\_user',  
MASTER_PASSWORD='password',  
MASTER_LOG_FILE='mysql-bin.000001',  
MASTER_LOG_POS=154;  
  
-- 从库启动复制  
START SLAVE;  

      

效果 :主库宕机时,从库自动切换为可读写状态,业务无感知。

2 服务熔断

场景 :支付服务响应延迟,导致订单服务线程池耗尽,引发连锁故障。

问题 :服务依赖链中某个环节异常,会像多米诺骨牌一样拖垮整个系统。

解决方案 :引入熔断器模式,例如Hystrix或Resilience4j。

Resilience4j熔断配置如下:


        
          
CircuitBreakerConfig config = CircuitBreakerConfig.custom()  
    .failureRateThreshold(50)  // 失败率超过50%触发熔断  
    .waitDurationInOpenState(Duration.ofMillis(1000))  
    .build();  
CircuitBreaker circuitBreaker = CircuitBreaker.of("paymentService", config);  
  
// 调用支付服务  
Supplier<String> supplier = () -> paymentService.call();  
Supplier<String> decoratedSupplier = CircuitBreaker  
    .decorateSupplier(circuitBreaker, supplier);  

      

效果 :当支付服务失败率飙升时,自动熔断并返回降级结果(如“系统繁忙,稍后重试”)。

3 流量削峰

场景 :秒杀活动开始瞬间,10万QPS直接击穿数据库连接池。

问题 :突发流量超过系统处理能力,导致资源耗尽。

解决方案 :引入消息队列(如Kafka、RocketMQ)做异步缓冲。

用户下单的系统流程图如下:

picture.image

RocketMQ生产者的示例代码:


        
          
DefaultMQProducer producer = new DefaultMQProducer("seckill\_producer");  
producer.setNamesrvAddr("127.0.0.1:9876");  
producer.start();  
Message msg = new Message("seckill\_topic", "订单数据".getBytes());  
producer.send(msg);  

      

效果 :将瞬时10万QPS的请求平滑处理为数据库可承受的2000 TPS。

4 动态扩容

场景 :日常流量100台服务器足够,但大促时需要快速扩容到500台。

问题 :固定资源无法应对业务波动,手动扩容效率低下。

解决方案 :基于Kubernetes的HPA(Horizontal Pod Autoscaler)。

K8s HPA 的配置如下:


        
          
apiVersion: autoscaling/v2  
kind: HorizontalPodAutoscaler  
metadata:  
  name: order-service-hpa  
spec:  
  scaleTargetRef:  
    apiVersion: apps/v1  
    kind: Deployment  
    name: order-service  
  minReplicas: 2  
  maxReplicas: 10  
  metrics:  
  - type: Resource  
    resource:  
      name: cpu  
      target:  
        type: Utilization  
        averageUtilization: 60  

      

效果 :CPU利用率超过60%时自动扩容,低于30%时自动缩容。

5 灰度发布

场景 :新版本代码存在内存泄漏,全量发布导致线上服务崩溃。

问题 :一次性全量发布风险极高,可能引发全局故障。

解决方案 :基于流量比例的灰度发布策略。

Istio流量染色配置如下:


        
          
apiVersion: networking.istio.io/v1alpha3  
kind: VirtualService  
metadata:  
  name: bookinfo  
spec:  
  hosts:  
  - bookinfo.com  
  http:  
  - route:  
    - destination:  
        host: reviews  
        subset: v1  
      weight: 90  # 90%流量走老版本  
    - destination:  
        host: reviews  
        subset: v2  
      weight: 10  # 10%流量走新版本  

      

效果 :新版本异常时,仅影响10%的用户,快速回滚无压力。

6 降级开关

场景 :推荐服务超时导致商品详情页加载时间从200ms飙升到5秒。

问题 :非核心功能异常影响核心链路用户体验。

解决方案 :配置中心增加降级开关,如果遇到紧急情况,能 动态降级非关键服务。

Apollo配置中心的示例代码如下:


        
          
@ApolloConfig  
private Config config;  
  
public ProductDetail getDetail(String productId) {  
    if(config.getBooleanProperty("recommend.switch", true)) {  
        // 调用推荐服务  
    }  
    // 返回基础商品信息  
}  

      

效果 :关闭推荐服务后,详情页响应时间恢复至200ms以内。

7 全链路压测

场景 :某金融系统在真实流量下暴露出数据库死锁问题。

问题 :测试环境无法模拟真实流量特征,线上隐患难以发现。

解决方案 :基于流量录制的全链路压测。

实施步骤

  1. 线上流量录制(如Jmeter+TCPCopy)
  2. 影子库隔离(压测数据写入隔离存储)
  3. 压测数据脱敏
  4. 执行压测并监控系统瓶颈

效果 :提前发现数据库连接池不足、缓存穿透等问题。

8 数据分片

场景 :用户表达到10亿行,查询性能断崖式下降。

问题 :单库单表成为性能瓶颈。

解决方案 :基于ShardingSphere的分库分表。

分库分表的配置如下:


        
          
sharding:  
  tables:  
    user:  
      actualDataNodes: ds\_${0..1}.user\_${0..15}  
      tableStrategy:  
        standard:  
          shardingColumn: user\_id  
          preciseAlgorithmClassName: HashModShardingAlgorithm  
          preciseAlgorithmType: HASH\_MOD  
          shardingCount: 16  

      

效果 :10亿数据分散到16个物理表,查询性能提升20倍。

9 混沌工程

场景 :某次机房网络抖动导致服务不可用3小时。

问题 :系统健壮性不足,故障恢复能力弱。

解决方案 :使用ChaosBlade模拟故障。

示例命令


        
          
# 模拟网络延迟  
blade create network delay --time 3000 --interface eth0  
  
# 模拟数据库节点宕机  
blade create docker kill --container-id mysql-node-1  

      

效果 :提前发现缓存穿透导致DB负载过高的问题,优化缓存击穿防护策略。

10 立体化监控

场景 :磁盘IOPS突增导致订单超时,但运维人员2小时后才发现。

问题 :监控维度单一,无法快速定位根因。

解决方案 :构建Metrics-Log-Trace三位一体监控体系。

技术栈组合

  • Metrics:Prometheus + Grafana(资源指标)
  • Log:ELK(日志分析)
  • Trace:SkyWalking(调用链追踪)

定位问题流程如下 :


        
          
CPU利用率 > 80% → 关联日志检索 → 定位到GC频繁 →   
追踪调用链 → 发现某个DAO层SQL未走索引  

      

效果 :故障定位时间从小时级缩短到分钟级。

总结

系统高可用建设就像打造一艘远洋巨轮。

冗余部署是双发动机,熔断降级是救生艇,监控体系是雷达系统。

但真正的关键在于:

  1. 故障预防 比故障处理更重要(如混沌工程)
  2. 自动化 是应对复杂性的唯一出路(如K8s弹性扩缩)
  3. 数据驱动 的优化才是王道(全链路压测+立体监控)

没有100%可用的系统,但通过这10个实战技巧,我们可以让系统的可用性从99%提升到99.99%。

这0.99%的提升,可能意味着每年减少8小时的故障时间——而这,正是架构师价值的体现。

最后欢迎 加入苏三的星球 ,你将获得:苏三AI项目、 商城微服务实战、秒杀系统实战 、 商城系统实战、秒杀系统实战、代码生成工具、系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。

还有1V1答疑、修改简历、职业规划、送书活动、技术交流。

picture.image

目前星球已经更新了5200+篇优质内容,还在持续爆肝中.....

星球已经被官方推荐了3次,收到了小伙伴们的一致好评。戳我加入学习,已有1600+小伙伴加入学习。

picture.image

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动 NoSQL 的实践与探索
随着 NoSQL 的蓬勃发展越来越多的数据存储在了 NoSQL 系统中,并且 NoSQL 和 RDBMS 的界限越来越模糊,各种不同的专用 NoSQL 系统不停涌现,各具特色,形态不一。本次主要分享字节跳动内部和火山引擎 NoSQL 的实践,希望能够给大家一定的启发。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论