Files
hi-server/ops/hifast-aws-standby-architecture-zh.md
T
shanshanzhong147 c4b2ebf7e1
Build docker and publish / build (20.15.1) (push) Has been cancelled
x
2026-05-10 10:41:50 -07:00

439 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 '<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 复制是否正常
### 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` 的接管与回切执行清单