Files
hi-server/ops/hifast-aws-standby-architecture-zh.md
shanshanzhong147 fd522b6c71
Build docker and publish / build (20.15.1) (push) Successful in 8m56s
path
2026-05-19 19:35:44 -07:00

20 KiB
Raw Permalink Blame History

Hifast AWS 主生产 + 外部备用 完整部署方案与访问架构

本文档整理当前已经实际落地的生产架构、访问链路、数据库与缓存主从关系、网络边界、故障切换方案,以及后续扩展建议。

目标是让团队在一个文档里就能看清:

  • 现在生产到底部署成了什么样
  • 请求是怎么进来的,数据是怎么流转的
  • AWS 与外部备用服务器分别承担什么角色
  • MySQL / Redis 的同步关系是什么
  • 故障时应该如何切换

0. 2026-05-13 验收摘要

  • 已确认 104.238.220.230 -> AWS RDS MySQL 连通,MySQL 外部从库健康:
    • 当前复制上游:hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com
    • Replica_IO_Running: Yes
    • Replica_SQL_Running: Yes
    • Seconds_Behind_Source: 0
  • 已确认 104.238.220.230 -> AWS EC2 Redis 主从健康:
    • 104role:slave
    • master_link_status:up
    • AWS Redis 主库 connected_slaves:1
  • 已修复应用侧 Redis 配置漂移:
    • 旧链路:127.0.0.1:6380 -> stunnel4 -> 旧 ElastiCache
    • 新链路:127.0.0.1:6379 -> 本机 Docker Redis
  • stunnel4 已停用并禁用自启,ppanel-server 日志里的 Redis i/o timeout 已停止出现。
  • 已确认 ppanel-server 当前运行方式为 Docker Compose 容器,而不是 systemd 服务:
    • Compose 文件:/opt/ppanel/docker-compose.cloud.yml
    • 配置文件:/opt/ppanel/configs/ppanel.yaml
    • 容器名:ppanel-server
    • 健康检查:curl http://127.0.0.1:8080/v1/common/heartbeat 返回正常
  • 旧自建安全组 hifast-hk-app-sghifast-hk-nginx-sg 已删除;当前 VPC 内仅保留:
    • hifast-hk-app-core-sg
    • hifast-hk-rds-core-sg
    • hifast-hk-web-sg
    • default
  • 目前已经达到“可用且关键链路已恢复”的状态。
  • 当前入口层属于已确认的过渡方案:
    • 现阶段公网入口仍在 hifast-hk-app-01
    • 独立 nginx 服务器已预留,待 AWS 后续资源到位后再迁移承接
  • 当前仍需要继续收敛的核心生产项只剩 1 个:
    • RDS 为了让 104 走公网白名单复制,当前仍依赖 hifast-hk-private-1b 子网临时挂到公网路由表,这不是最终规范形态。
  • 已完成的下一步准备:
    • 已创建纯公网子网专用的 DB subnet grouphifast-hk-rds-public-only-sgprep
    • 子网包含:
      • subnet-070e3f264a9c79f32 hifast-hk-public-1a
      • subnet-00cb5add705c447c8 hifast-hk-public-1b
  • 已创建专用 S3 备份桶:
    • hifast-prod-backups-200810848252-ap-east-1
    • 当前状态:private
    • 当前状态:versioning enabled

1. 当前实际环境

1.1 AWS 区域

  • Region: ap-east-1
  • 说明:香港区

1.2 已确认资源

应用服务器

  • 名称:hifast-hk-app-01
  • Instance ID: i-079cd9d3ef3748714
  • 角色:当前实际生产入口 / Nginx / 业务服务 / AWS 侧 Redis 主库宿主机
  • 私网 IP: 10.0.1.201
  • 公网 IP: 18.163.33.75
  • 业务服务运行方式:Docker Compose
  • 业务容器:ppanel-server
  • 部署目录:/opt/ppanel
  • 实际配置文件:/opt/ppanel/configs/ppanel.yaml

独立 Nginx 服务器

  • 名称:hifast-hk-nginx-01
  • Instance ID: i-0701d54bf2c6bf594
  • 角色:计划中的独立入口机
  • 私网 IP: 10.0.1.175
  • 当前状态:stopped
  • 当前说明:已经只绑定 hifast-hk-web-sg,但目前并未承接正式流量

MySQL 主库

  • 类型:AWS RDS MySQL
  • 实例名:hifast-mysql-prod-v2
  • Endpoint: hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com
  • 角色:生产主库
  • Engine: MySQL 8.4.8
  • Publicly accessible: Yes
  • Multi-AZ: No
  • Backup retention: 7 days
  • Deletion protection: On
  • 当前数据库实际体量:约 187.41 MB
  • 当前表数量:37
  • 当前 user 表记录数:45076

Redis 主库

  • 部署位置:AWS EC2 hifast-hk-app-01
  • 部署方式:Docker
  • 容器名:hifast-redis
  • 版本:redis:8.2.1
  • 访问端口:6379
  • 主库出口地址:18.163.33.75:6379
  • 应用当前实际连接:127.0.0.1:6379
  • 认证方式:已启用密码认证

外部备用服务器

  • IP: 104.238.220.230
  • OS: Ubuntu 24.04 LTS
  • 角色:异地备用节点
  • 当前状态:已部署与 AWS 相同的业务服务
  • 当前 MySQL 状态:外部只读从库
  • 当前 Redis 部署方式:宿主机原生安装
  • 当前 Redis 版本:8.6.3
  • 当前 Redis 角色:AWS Redis 主库的从库

S3 备份桶

  • Bucket: hifast-prod-backups-200810848252-ap-east-1
  • Region: ap-east-1
  • Public access: blocked
  • Versioning: enabled

2. 架构总览

flowchart TB
    USER["用户 / 客户端"] --> DNS["域名 / DNS / 入口层"]
    DNS --> APP["AWS EC2\nhifast-hk-app-01\n18.163.33.75\n10.0.1.201"]

    APP --> RDS["AWS RDS MySQL\nhifast-mysql-prod-v2\n主库"]
    APP --> REDISM["AWS Redis 主库\nDocker redis:8.2.1\n18.163.33.75:6379"]

    RDS -. MySQL 备用 / 同步 .-> MYSQLS["104.238.220.230\nMySQL 备用库"]
    REDISM -. Redis 主从复制 .-> REDISS["104.238.220.230\n原生 Redis 8.6.3\n从库"]

    subgraph AWS["AWS ap-east-1"]
        APP
        RDS
        REDISM
    end

    subgraph BACKUP["异地备用节点"]
        MYSQLS
        REDISS
    end

3. 访问链路

3.1 用户访问链路

当前生产访问链路可以概括为:

用户 -> 域名 / DNS -> AWS EC2 应用机 -> MySQL / Redis

说明:

  • 当前主应用入口实际在 hifast-hk-app-01
  • hifast-hk-app-01 同时承担 Nginx、业务服务、Redis 主库。
  • 当前业务服务不是 systemd 单进程部署,而是由 /opt/ppanel/docker-compose.cloud.yml 管理的 ppanel-server 容器提供 8080
  • 独立入口机 hifast-hk-nginx-01 已存在,但当前仅作为后续资源开通后的迁移目标。
  • MySQL 在 AWS RDS。
  • Redis 不在 ElastiCache,而是在 EC2 本机通过 Docker 提供。

3.2 应用访问数据链路

应用侧内部依赖关系如下:

App / Nginx
  -> RDS MySQL 主库
  -> AWS EC2 Redis 主库

3.3 备用链路

备用服务器 104.238.220.230 当前已经部署同样的业务服务,但正常情况下不直接承担正式流量,而是承担:

  • 备用应用节点
  • MySQL 异地备用
  • Redis 异地从库

也就是说,正常情况下:

  • 用户正式流量默认不走 104
  • 104 已具备接管业务的基础应用环境
  • 104 主要处于待命同步和灾备状态

4. 网络与安全边界

4.1 当前安全组

截至 2026-05-13VPC vpc-09fc384522517debc 内仅保留 4 个安全组:

  • default
  • hifast-hk-app-core-sg
  • hifast-hk-rds-core-sg
  • hifast-hk-web-sg

其中绑定关系已经收敛为:

  • hifast-hk-app-01 -> hifast-hk-app-core-sg
  • hifast-hk-nginx-01 -> hifast-hk-web-sg
  • hifast-mysql-prod-v2 -> hifast-hk-rds-core-sg

旧组:

  • hifast-hk-app-sg
  • hifast-hk-nginx-sg

已经删除,不再使用。

4.2 当前入站规则

hifast-hk-app-core-sg

  • 22/tcp <- 0.0.0.0/0
  • 6379/tcp <- 104.238.220.230/32
  • 8080/tcp <- hifast-hk-web-sg

hifast-hk-rds-core-sg

  • 3306/tcp <- 104.238.220.230/32
  • 3306/tcp <- hifast-hk-app-core-sg

hifast-hk-web-sg

  • 22/tcp <- 0.0.0.0/0
  • 80/tcp <- 0.0.0.0/0
  • 443/tcp <- 0.0.0.0/0

4.3 Redis 网络关系

flowchart LR
    SG["hifast-hk-app-core-sg"] --> REDIS["AWS Redis 主库\n18.163.33.75:6379"]
    STANDBY["104.238.220.230/32"] --> SG

4.4 RDS 访问原则

RDS 当前状态已经比之前干净很多:

  • 当前只对白名单和应用安全组开放 3306
  • 已移除 3306 <- 0.0.0.0/0
  • 当前 RDS 仅绑定 hifast-hk-rds-core-sg

建议原则:

  • 不开放 0.0.0.0/0 到 MySQL 3306
  • 不开放 0.0.0.0/0 到 Redis 6379

4.5 当前仍需继续收敛的网络点

4.5.1 入口层当前属于过渡方案,不作为本阶段阻塞项

当前运行形态是:

  • hifast-hk-app-01 本机 nginx 正在监听 80/443
  • hifast-hk-nginx-01 当前停止

但当前安全组设计是按“独立 nginx 机”拆的:

  • hifast-hk-web-sghifast-hk-nginx-01
  • hifast-hk-app-core-sghifast-hk-app-01

这意味着当前真实入口和安全组角色划分还没有完全一致。

但这一点已经被确认为过渡设计,不作为当前阶段必须整改的问题。后续待 AWS 新资源到位后,再把公网入口迁到独立 nginx 服务器即可。

4.5.2 RDS 公网复制链路仍是当前唯一核心结构性问题

为了让 104.238.220.230 通过公网白名单访问 RDS,当前实际依赖的是:

  • RDS PubliclyAccessible = true
  • RDS ENI 仍在 subnet-0dcf46db665b6d8a7
  • 该子网名称是 hifast-hk-private-1b
  • 但这个子网当前被临时关联到了公网路由表

这能用,但不属于最终规范的“纯公网子网组”设计。

本轮已经额外完成的准备动作:

  • 已新建纯公网 DB subnet grouphifast-hk-rds-public-only-sgprep
  • 该组状态:Complete
  • 该组仅包含两条公网子网:
    • hifast-hk-public-1a
    • hifast-hk-public-1b

当前结论:

  • 不建议继续在现有生产 RDS 上反复试在线切子网组。
  • 更稳的收敛方案是:新建一台使用规范公网子网组的生产 RDS,再做一次短切换。
  • 由于当前库体量只有约 187 MB,这条路线的执行成本并不高,风险也比在现网主库上硬改更可控。

4.6 104 如何连接 AWS

这里要特别区分:

  • 104 连接 AWS 数据层
  • 本地电脑登录 AWS EC2

这不是同一件事。

4.6.1 104 连接 AWS Redis 的方式

104.238.220.230 连接 AWS Redis,不是通过 PEM 证书,也不是通过 SSH 登录 AWS 机器,而是直接作为 Redis 从库去访问 AWS Redis 主库:

  • 目标地址:18.163.33.75:6379
  • 连接方式:TCP
  • 认证方式:Redis 密码
  • 网络前提:AWS EC2 安全组已放行 104.238.220.230/32 -> 6379

也就是说:

104 Redis 从库 -> 直连 AWS Redis 主库公网地址 -> 密码认证 -> 建立复制

示意命令:

redis-cli -h 18.163.33.75 -p 6379 -a '<REDIS_PASSWORD>'

4.6.2 104 连接 AWS MySQL RDS 的方式

104.238.220.230 连接 AWS RDS,也不是通过 PEM 证书,而是通过数据库连接:

  • 目标地址:hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306
  • 连接方式:MySQL TCP
  • 认证方式:MySQL 用户名 + 密码
  • 网络前提:RDS 白名单或安全组放行 104.238.220.230

也就是说:

104 MySQL 从库 -> 直连 AWS RDS endpoint -> 账号密码认证 -> 建立复制

示意命令:

mysql -h hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com -u admin -p

4.6.3 本地电脑登录 AWS EC2 的方式

本地电脑这边之前进入 AWS EC2,用的不是 hifast-hk-app-01-key.pem,而是:

  • AWS Console
  • EC2 Instance Connect
  • 浏览器里的 Web SSH 终端

所以当前要理解成 3 条不同链路:

  1. 本地电脑 -> AWS 控制台 -> EC2 Instance Connect -> AWS EC2
  2. 104 -> AWS Redis 主库公网地址 -> Redis 密码认证
  3. 104 -> AWS RDS endpoint -> MySQL 用户密码认证

4.6.4 关键结论

当前灾备链路里,104 与 AWS 数据同步不依赖 .pem 证书文件。

真正依赖的是:

  • Redis 安全组放行
  • RDS 白名单 / 安全组放行
  • 正确的 Redis 密码
  • 正确的 MySQL 账号密码

5. Redis 实际部署与同步状态

5.1 AWS Redis 主库

  • 部署方式:Docker
  • 版本:8.2.1
  • 主库地址:18.163.33.75:6379
  • 运行容器:hifast-redis

5.2 104 Redis 从库

  • 部署方式:宿主机原生安装
  • 版本:8.6.3
  • 角色:replica / slave

5.3 Redis 主从状态

最终已验证结果:

  • 104 上 Redisrole:slave
  • 104 上 Redismaster_link_status:up
  • AWS Redis 主库:connected_slaves:1
  • AWS Redis 主库识别到从库:104.238.220.230:6379

5.4 Redis 验证结果

已做过的验证:

  • 104 连接 AWS Redis 主库,认证成功
  • AWS 主库写入测试键
  • 104 从库成功读取测试键
  • 2026-05-13 已确认应用机本地 ppanel-server -> 127.0.0.1:6379 建立稳定连接
  • 2026-05-13 已确认旧 stunnel4 -> ElastiCache 链路下线后,应用日志不再出现 Redis i/o timeout

测试键:

  • key: hifast_replication_test
  • value: ok_20260510

5.5 Redis 主从拓扑

flowchart LR
    REDISMASTER["AWS Redis 主库\n18.163.33.75:6379\nDocker redis:8.2.1"]
    REDISSLAVE["104.238.220.230\n原生 Redis 8.6.3\nrole: slave"]
    REDISMASTER --> REDISSLAVE

6. MySQL 部署与备用关系

6.1 主库角色

  • 主库在 AWS RDS MySQL
  • 实例:hifast-mysql-prod-v2

6.2 外部备用角色

  • 104.238.220.230 上存在 MySQL 备用用途
  • 目标是让 104 尽量实时同步 AWS 数据

6.3 当前文档说明

MySQL 当前已经完成实际验收,不再只是“待确认”状态。

2026-05-13 验收结果:

  • Source_Host = hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com
  • Replica_IO_Running = Yes
  • Replica_SQL_Running = Yes
  • Seconds_Behind_Source = 0
  • read_only = ON
  • super_read_only = ON

这表示 104 当前是健康的只读外部备用库。

MySQL 这部分在此前已经有专门 runbook:

7. 当前生产方案的真实特点

这套已经落地的架构,不是传统的全 AWS 托管标准形态,而是偏实用的混合方案:

  • 应用和当前实际公网入口在 AWS 同一台 EC2
  • MySQL 在 AWS RDS
  • Redis 在 AWS EC2 本机
  • MySQL / Redis 均向外部服务器 104 做灾备
  • 旧 ElastiCache / stunnel 链路已经退出当前生产路径

它的优点:

  • 成本相对可控
  • Redis 可完全自主控制
  • 外部备用机可以独立接管

它的代价:

  • Redis 高可用需要人工切换
  • 外部灾备不是全自动故障转移
  • 应用切换需要明确操作步骤

8. 故障切换方案

8.1 正常状态

flowchart TD
    A["用户访问"] --> B["AWS EC2 应用机"]
    B --> C["AWS RDS MySQL 主库"]
    B --> D["AWS Redis 主库"]
    C -. 同步 .-> E["104 MySQL 备用"]
    D -. 复制 .-> F["104 Redis 从库"]

8.2 AWS 故障后的目标切换状态

flowchart TD
    A["AWS 故障"] --> B["应用入口切到 104"]
    B --> C["104 MySQL 提供主服务"]
    B --> D["104 Redis 提升为主库"]
    D --> E["应用连接 104 Redis"]
    C --> F["应用连接 104 MySQL"]

8.2.1 Nginx 是否可以直接切到 104

可以,但前提不是“只切 Nginx 就完成故障切换”。

因为 104 虽然已经部署了同样的业务服务,但如果故障发生时:

  • Redis 还保持从库只读状态
  • MySQL 还没有切成可写主角色
  • 应用配置还没有确认指向 104 本机数据层

那么即使 Nginx 已经把流量转到 104,业务也可能仍然无法正常写入。

所以更准确的原则是:

104 已具备应用接管能力,Nginx 切换可以作为最后一步对外放流量动作,但不能作为唯一动作。

8.3 Redis 切换动作

当 AWS Redis 不可用时,104 上的 Redis 需要解除主从关系:

redis-cli -a '<REDIS_PASSWORD>' REPLICAOF NO ONE

切换后:

  • 104 Redis 从库变为主库
  • 业务应用把 Redis 地址改到 104.238.220.230:6379

8.4 MySQL 切换动作

当 AWS RDS 不可用时,需要让 104 MySQL 接管写流量。

这部分是否能立即切,需要依赖:

  • 当前 104 MySQL 是否是健康从库
  • 是否已经取消只读
  • 应用数据库配置是否能快速切换到 104

8.5 应用切换动作

应用层需要准备至少这 2 个切换点:

  • MySQL 连接地址切换到 104
  • Redis 连接地址切换到 104

如果应用入口也要迁移到 104,还需要:

  • 域名解析切换
  • 或者网关 / 入口切换

8.6 推荐的实际切换顺序

因为 104 已经部署同样的应用服务,所以 AWS 故障时推荐按下面顺序操作:

  1. 确认 104 上业务服务和 Nginx 进程正常。
  2. 104 上 Redis 从库提升为主库。
  3. 104 上 MySQL 从库切换为可写主库。
  4. 确认 104 上应用配置已指向本机 MySQL / Redis。
  5. 最后再把 Nginx 上游或域名流量切到 104

可以把它理解成:

先数据接管 -> 再应用确认 -> 最后入口切流量

9. 建议的运维操作顺序

9.1 平时

平时重点看:

  • AWS EC2 是否在线
  • RDS 是否在线
  • AWS Redis 主库是否在线
  • 104 Redis 从库是否 master_link_status:up
  • 104 MySQL 复制是否正常
  • ppanel-server 容器是否 Up
  • ppanel-server 日志中是否再次出现 Redis i/o timeout
  • stunnel4 是否保持 inactive

9.2 Redis 故障时

  1. 确认 AWS Redis 主库不可恢复。
  2. 104 执行 REPLICAOF NO ONE
  3. 修改应用 Redis 地址到 104.238.220.230:6379
  4. 验证应用读写 Redis 正常。

9.3 MySQL 故障时

  1. 确认 RDS 故障。
  2. 确认 104 MySQL 数据已同步到最新可用点。
  3. 去掉 104 MySQL 只读限制。
  4. 修改应用 MySQL 地址到 104
  5. 验证应用读写数据库正常。

9.4 整体 AWS 故障时

  1. 把 Redis 主角色切到 104
  2. 把 MySQL 主角色切到 104
  3. 确认 104 上同版本应用服务正常。
  4. 把应用入口切到备用应用节点。
  5. 更新 DNS 或 Nginx 上游流量入口。
  6. 验证用户访问链路。

10. 当前方案与理想方案的差异

10.1 当前实际方案

DNS -> hifast-hk-app-01(Nginx + App + Redis) -> RDS MySQL -> 104 灾备

10.2 理想生产方案

从长期稳定性看,更推荐未来演进为:

DNS / CDN -> ALB -> 多台 EC2 App -> RDS MySQL -> 托管 Redis / 或高可用 Redis

异地灾备继续保留:

  • AWS 生产
  • 104 异地接管

10.3 当前最值得继续补的项

建议按优先级补齐:

  1. 把 RDS 从“private 子网挂公网路由”的临时方案,收敛成真正的公网 DB subnet group,或改成私网复制方案
  2. 明确 104 应用接管脚本与启动检查项
  3. 明确 MySQL 故障切换脚本
  4. 明确 Redis 故障切换脚本
  5. 明确域名 / DNS 切换方式
  6. 做一次完整灾备演练
  7. 待 AWS 新资源到位后,再把公网入口迁到独立 nginx 服务器

10.4 RDS 推荐收敛路线

当前原先规划的“新建规范 RDS 再切换”路线已经完成,现网主库已经是 hifast-mysql-prod-v2

后续更推荐的正式路线是:

  1. 继续以 hifast-mysql-prod-v2 作为当前生产主库
  2. 确认其持续使用 hifast-hk-rds-public-only-sgprep
  3. 安全组持续只放:
    • 104.238.220.230/32 -> 3306
    • hifast-hk-app-core-sg -> 3306
  4. 持续确认应用连接目标为 hifast-mysql-prod-v2
  5. 持续确认 104 的外部复制目标为 hifast-mysql-prod-v2
  6. 验证通过后,再安排旧 RDS 下线

这条路线的优点:

  • 最终拓扑规范清晰
  • 不需要继续保留“private 子网挂公网路由”的临时设计
  • 对当前现网主库的扰动最小
  • 当前数据库体量较小,迁移成本可控

11. 建议的下一版目标拓扑

flowchart TB
    USER["用户 / 客户端"] --> DNS["DNS / CDN / 入口层"]
    DNS --> APPAWS["AWS 应用集群"]
    DNS -. 故障时切换 .-> APPBK["104 备用应用节点"]

    APPAWS --> RDSAWS["AWS RDS MySQL 主库"]
    APPAWS --> REDISAWS["AWS Redis 主库"]

    RDSAWS -. 同步 .-> MYSQLBK["104 MySQL 备用"]
    REDISAWS -. 复制 .-> REDISBK["104 Redis 备用"]

    APPBK --> MYSQLBK
    APPBK --> REDISBK

12. 本文档结论

截至当前,已经可以确认的生产与灾备状态是:

  • AWS 是主生产环境
  • 应用当前跑在 hifast-hk-app-01
  • MySQL 主库在 AWS RDS
  • Redis 主库在 AWS EC2 Docker
  • 104.238.220.230 是异地备用节点
  • 104 已部署与 AWS 相同的业务服务
  • 104 上 Redis 已切为宿主机原生安装
  • 104 Redis 已成功作为 AWS Redis 主库的从库在线同步
  • 104 MySQL 已恢复并保持健康复制
  • 应用已经切回当前真实可用的本机 Redis 主库
  • stunnel4 -> ElastiCache 链路已经退出生产路径

如果后续要继续完善这份方案,优先补充:

  • RDS 子网与公网访问模型收敛
  • 入口域名 / DNS 切换细则
  • 应用层在 104 的接管与回切执行清单
  • 待资源到位后的独立 nginx 迁移清单