admin管理员组

文章数量:1437160

谁怕宕机?聊聊我是怎么防住单点故障的

谁怕宕机?聊聊我是怎么防住单点故障的


一、前言:别等系统挂了,才想起“高可用”这回事

说实话,刚入行的时候,我对“高可用”这三个字没什么概念。那时候只想着系统跑起来就行,能处理请求、能写数据库、能返回数据,一切OK!

直到有一天,凌晨两点,电话响了。

“兄弟,你们系统挂了。用户报错,页面502,接口响应超时。”

我迷迷糊糊爬起来一看,原因是:数据库单点故障。因为主库挂了,而没有任何备库、故障转移、负载均衡的机制。

从那之后,我就明白了一句话:可用性不是一个“功能”,它是一种责任。

今天这篇文章,我就想聊聊我在工作中是怎么构建高可用系统、防止单点故障的,通俗点讲,就是别再让系统“一个点挂了就全垮”。


二、搞清楚:什么是“单点故障”(SPOF)

单点故障,全称是 Single Point of Failure,意思就是:

“系统中某一个组件一旦出问题,就会导致整个系统崩溃。”

这就像你家电源只有一个插座,一跳闸,全家黑灯瞎火。

常见的单点故障位置包括:

  • 应用服务:只有一个Nginx或Tomcat;
  • 数据库:主库挂了就玩完;
  • 缓存层:Redis挂掉就无法登录;
  • 消息队列:RabbitMQ宕了消息就丢;
  • 存储系统:只有一份数据,丢了不可恢复。

三、策略一:服务多副本+负载均衡

我做的第一步是“不要让服务只部署一份”。比如我们的 Java Web 项目原本只跑在一台服务器上,只要那台机器挂了,系统就崩。

改进方式很简单:

  1. 把服务部署多个副本;
  2. 用 Nginx 或 LVS 做负载均衡;
  3. 添加健康检查,自动剔除不健康节点。

Nginx配置简单示例如下:

代码语言:nginx复制
upstream backend {
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}

一旦某个服务实例挂了,Nginx 会自动切流量到其他节点上,不至于让用户感知异常。


四、策略二:数据库主从+故障切换

数据库这块是重灾区。我们之前用 MySQL 单机,写多读多,压力大、挂了还恢复慢。

后来我部署了 MySQL主从复制 + Keepalived + MHA(或ProxySQL)

工作原理如下:

  • 主库负责写;
  • 从库负责读;
  • 一旦主库挂掉,系统自动切换到备库当主库;
  • 客户端访问数据库的 IP 不变,由 Keepalived 提供虚拟 IP。

数据库高可用的Keepalived配置片段如下:

代码语言:conf复制
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    virtual_ipaddress {
        192.168.1.100
    }
}

这样,我们就能做到“主库挂了,服务不挂”。


五、策略三:Redis高可用:主从 + Sentinel

Redis 是最容易出问题的单点。我们曾因为 Redis 挂了,导致所有登录状态丢失、接口鉴权失败,用户大面积掉线。

现在我的 Redis 部署方式是:

  • 主从复制;
  • Sentinel 自动监控 + 故障转移;
  • 客户端支持自动发现主节点。

Sentinel 的配置非常轻便,比如这样一段:

代码语言:bash复制
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

有了 Sentinel,Redis 主节点挂了,Sentinel 会在几秒内选出新的主节点并通知客户端。


六、策略四:异地多活,准备灾难恢复

最开始我们只在一台机房部署。后面经历过一次“机房断电”,我被老板喊去会议室批斗了一整天。

后面,我做了“异地多活”的部署,核心做法包括:

  • 核心业务双活部署(东区+西区);
  • 数据库双写同步(分布式一致性保障);
  • 接入层通过 DNS 或云 WAF 统一调度。

用一个脚本简单示意:

代码语言:bash复制
if curl -s http://east-region/health | grep "OK"; then
    export ENDPOINT=http://east-region
else
    export ENDPOINT=http://west-region
fi

现在一个机房挂了,另一个立刻接盘。


七、策略五:监控 + 异常感知 + 自愈机制

再牛的架构,如果你没人盯着也白搭。于是我加上了三道“哨兵”:

  1. Prometheus + Grafana:实时监控服务、数据库、Redis等指标;
  2. Alertmanager + Webhook:出问题自动发钉钉/短信/电话;
  3. Ansible/自动脚本:故障发现后自动拉起服务或切换节点。

比如,监控服务 CPU 超过 90%,就触发自动扩容脚本:

代码语言:bash复制
if [ $(top -bn1 | grep "Cpu(s)" | awk '{print $2}') > 90 ]; then
    ./scale_service.sh
fi

八、结尾:高可用不是“加服务”,而是加责任感

说到底,高可用不是技术问题,而是责任感。

它意味着你要假设:

  • 所有服务都会挂;
  • 所有节点都不可信;
  • 所有依赖都可能抽风;
  • 但你,不能崩。

本文标签: 谁怕宕机聊聊我是怎么防住单点故障的