# Hifast AWS 主生产 + 外部备用 完整部署方案与访问架构 本文档整理当前已经实际落地的生产架构、访问链路、数据库与缓存主从关系、网络边界、故障切换方案,以及后续扩展建议。 目标是让团队在一个文档里就能看清: - 现在生产到底部署成了什么样 - 请求是怎么进来的,数据是怎么流转的 - AWS 与外部备用服务器分别承担什么角色 - MySQL / Redis 的同步关系是什么 - 故障时应该如何切换 ## 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: `43.198.248.161` #### MySQL 主库 - 类型:`AWS RDS MySQL` - 实例名:`hifast-mysql-prod` - 角色:生产主库 #### Redis 主库 - 部署位置:`AWS EC2 hifast-hk-app-01` - 部署方式:`Docker` - 容器名:`hifast-redis` - 版本:`redis:8.2.1` - 访问端口:`6379` - 主库出口地址:`43.198.248.161:6379` #### 外部备用服务器 - IP: `104.238.220.230` - OS: `Ubuntu 24.04 LTS` - 角色:异地备用节点 - 当前状态:已部署与 AWS 相同的业务服务 - 当前 Redis 部署方式:`宿主机原生安装` - 当前 Redis 版本:`8.6.3` - 当前 Redis 角色:`AWS Redis 主库的从库` ## 2. 架构总览 ```mermaid flowchart TB USER["用户 / 客户端"] --> DNS["域名 / DNS / 入口层"] DNS --> APP["AWS EC2\nhifast-hk-app-01\n43.198.248.161\n10.0.1.201"] APP --> RDS["AWS RDS MySQL\nhifast-mysql-prod\n主库"] APP --> REDISM["AWS Redis 主库\nDocker redis:8.2.1\n43.198.248.161: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` 说明: - 当前主应用入口在 AWS EC2。 - EC2 同时承担业务服务入口。 - MySQL 在 AWS RDS。 - Redis 不在 ElastiCache,而是在 EC2 本机通过 Docker 提供。 ### 3.2 应用访问数据链路 应用侧内部依赖关系如下: ```text App / Nginx -> RDS MySQL 主库 -> AWS EC2 Redis 主库 ``` ### 3.3 备用链路 备用服务器 `104.238.220.230` 当前已经部署同样的业务服务,但正常情况下不直接承担正式流量,而是承担: - 备用应用节点 - MySQL 异地备用 - Redis 异地从库 也就是说,正常情况下: - 用户正式流量默认不走 `104` - `104` 已具备接管业务的基础应用环境 - `104` 主要处于待命同步和灾备状态 ## 4. 网络与安全边界 ### 4.1 EC2 安全组 - 安全组名称:`hifast-hk-app-sg` - 安全组 ID: `sg-09266fb27bde15714` 已确认规则: - Redis `6379/tcp` - 来源:`104.238.220.230/32` 这条规则的作用是: - 允许外部备用服务器 `104.238.220.230` 连到 AWS Redis 主库 - 避免 Redis 对全网开放 ### 4.2 Redis 网络关系 ```mermaid flowchart LR SG["EC2 Security Group\nsg-09266fb27bde15714"] --> REDIS["AWS Redis 主库\n43.198.248.161:6379"] STANDBY["104.238.220.230/32"] --> SG ``` ### 4.3 RDS 访问原则 RDS 不应该对公网全开放。 推荐且已执行过的方向是: - 只对白名单源 IP 开放 `3306` - 如果 `104.238.220.230` 需要做外部从库,则只放行这个 IP 建议原则: - 不开放 `0.0.0.0/0` 到 MySQL `3306` - 不开放 `0.0.0.0/0` 到 Redis `6379` ## 5. Redis 实际部署与同步状态 ### 5.1 AWS Redis 主库 - 部署方式:Docker - 版本:`8.2.1` - 主库地址:`43.198.248.161:6379` - 运行容器:`hifast-redis` ### 5.2 104 Redis 从库 - 部署方式:宿主机原生安装 - 版本:`8.6.3` - 角色:`replica / slave` ### 5.3 Redis 主从状态 最终已验证结果: - `104` 上 Redis:`role:slave` - `104` 上 Redis:`master_link_status:up` - AWS Redis 主库:`connected_slaves:1` - AWS Redis 主库识别到从库:`104.238.220.230:6379` ### 5.4 Redis 验证结果 已做过的验证: - 从 `104` 连接 AWS Redis 主库,认证成功 - AWS 主库写入测试键 - `104` 从库成功读取测试键 测试键: - key: `hifast_replication_test` - value: `ok_20260510` ### 5.5 Redis 主从拓扑 ```mermaid flowchart LR REDISMASTER["AWS Redis 主库\n43.198.248.161: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` ### 6.2 外部备用角色 - `104.238.220.230` 上存在 MySQL 备用用途 - 目标是让 `104` 尽量实时同步 AWS 数据 ### 6.3 当前文档说明 Redis 的主从状态已经在本次执行中完成并验证。 MySQL 这部分在此前已经有专门 runbook: - [ops/aws-rds-external-replica-runbook.md](/Users/Apple/code_vpn/vpn/ppanel-server/ops/aws-rds-external-replica-runbook.md) 如果要把 MySQL 也完全纳入同一灾备演练,需要继续确认: - `104` 当前 MySQL 的同步线程状态 - `SHOW REPLICA STATUS\G` 是否仍然正常 - RDS 到 `104` 的白名单是否仍然保留 ## 7. 当前生产方案的真实特点 这套已经落地的架构,不是传统的全 AWS 托管标准形态,而是偏实用的混合方案: - 应用在 AWS EC2 - MySQL 在 AWS RDS - Redis 在 AWS EC2 本机 - MySQL / Redis 均向外部服务器 `104` 做灾备 它的优点: - 成本相对可控 - Redis 可完全自主控制 - 外部备用机可以独立接管 它的代价: - Redis 高可用需要人工切换 - 外部灾备不是全自动故障转移 - 应用切换需要明确操作步骤 ## 8. 故障切换方案 ### 8.1 正常状态 ```mermaid 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 故障后的目标切换状态 ```mermaid 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 需要解除主从关系: ```bash redis-cli -a '' 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 复制是否正常 ### 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 -> AWS EC2(App + Nginx) -> RDS MySQL + EC2 Redis -> 104 灾备` ### 10.2 理想生产方案 从长期稳定性看,更推荐未来演进为: `DNS / CDN -> ALB -> 多台 EC2 App -> RDS MySQL -> 托管 Redis / 或高可用 Redis` 异地灾备继续保留: - AWS 生产 - 104 异地接管 ### 10.3 当前最值得继续补的项 建议按优先级补齐: 1. 明确 `104` 应用接管脚本与启动检查项 2. 明确 MySQL 故障切换脚本 3. 明确 Redis 故障切换脚本 4. 明确域名 / DNS 切换方式 5. 做一次完整灾备演练 ## 11. 建议的下一版目标拓扑 ```mermaid 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 主库的从库在线同步 如果后续要继续完善这份方案,优先补充: - MySQL 最终同步状态复核 - 入口域名 / DNS 切换细则 - 应用层在 `104` 的接管与回切执行清单