AWS→GCP:一个人,三周,零预演,万级长连接迁徙实录
背景
公司战略调整,业务需从 AWS 迁移至 GCP。受限于客观条件,需在三周内独立完成。
为什么只有我一个人?
-
其他成员正在跟进定位器上线项目,有同事远赴欧洲现场测试,需远程对接,无法抽身
-
我本身承担架构、安全、运维、核心代码迭代四重角色,项目从0开始亲手迭代了7年
-
整个项目,只有我最熟悉所有细节,在零预演的约束下,除了测试,其他人只会帮倒忙
不是团队不想帮,是确实帮不上。这个迁移,只能我来。
真实工作路线
| 时间 | 事件 |
|---|---|
| 3月底 | 收到迁移命令,开始推演方案 |
| 4月初 | 被视觉AI紧急任务打断,迁移暂停 |
| 5月8日 | AI demo 完成,接到“5月31日前必须完成欧美双节点迁移”的死命令 |
| 5月9日 - 5月30日 | 实际迁移窗口(零预演,边干边切) |
| 5月31日 | 欧美双节点迁移完成 |
范围
- 欧洲节点:万级在线设备,仅服务欧洲地区
- 北美节点:万级 TCP 长连接 + 万级短连接设备,服务除中国和欧洲外的全球地区
- 中国节点:设备量约北美节点的两倍,仅服务中国地区
本次仅迁移欧美节点。
目标
业务平稳过渡,用户无感。
整体技术架构
终端层 → TCP 长连接设备(自定义协议)
接入层 → 基于 Netty 的网关集群,按区域部署
业务层 → 设备管理 / 指令下发 / 权限 / 调度
数据与消息层 → MySQL(数据存储)、RocketMQ(异步消息)、Redis(缓存)、MinIO(文件存储,原 FastDFS,因视觉 AI 升级)—— 所有组件容器化升级
用户层 → HTTP 短连接
通信链路
-
场景一:用户与设备在同一区域(同节点)
1. 下行控制链路(用户 App 下发设备指令)
用户 App → 业务网关 → 设备业务服务(请求挂起阻塞)→ MQ 流转 → 设备网关 → IoT 设备执行 → 结果回传 → 设备网关回写 MQ → 业务服务唤醒阻塞请求 → 最终结果原路返回至用户 App
关键特征: 请求挂起阻塞,等待设备响应后才返回,实现同步控制效果。
2. 上行上报链路(设备主动上报状态、数据、告警)
IoT 设备主动上报 → 设备网关 → MQ 流转 → 后端业务服务消费处理核心逻辑 → 重要告警、状态变更调用第三方推送直达用户 App → 非核心数据规整归档 → 回写 MQ → 设备网关 → IoT 设备
关键特征: 重要数据实时推送,非核心数据异步归档,链路闭环(MQ 回写用于后续下行动作)。
-
场景二: 用户出差,人在欧洲,设备在中国
1. 下行控制链路(用户 App 下发设备指令)
用户 App(欧洲)→ 业务网关(欧洲)→ 本地调度服务 → 数据中心(跨境寻址路由)→ 业务网关(中国)→ 业务服务下发指令 → MQ 流转 → 设备网关(中国)→ 设备执行(中国)→ 结果回传 → 原路返回 → 用户 App(欧洲)
2. 上行上报链路(设备主动上报状态、数据、告警): 与场景一上行上报链路一致。
关键特征: 跨境寻址路由——根据用户账号归属地,将请求路由到正确的区域网关,而非就近处理。
-
场景三: 设备第一网关连接失败,自动切换至第二网关, 导致用户在中国,设备连接了欧洲设备网关
1. 下行控制链路(用户 App 下发设备指令)
用户 App(中国)→ 业务网关(中国)→ 设备业务服务(请求挂起阻塞,发现设备异地上线)→ HTTP → 本地调度服务 → 中转 → 数据中心(跨境寻址路由)→ 中转 → 设备网关(欧洲)→ IoT 设备 → 结果回传 → 原路返回 → 用户 App(中国)
2. 上行上报链路(设备主动上报状态、数据、告警)
IoT 设备(欧洲)→ 设备网关(欧洲)→ HTTP → 本地调度服务 → 中转 → 数据中心(跨境寻址路由)→ 中转 → 设备归属区域设备网关(中国)→ 请求透传 → 业务服务处理 → 重要告警、状态变更调用第三方推送直达用户 App(中国)→ 非核心数据规整归档 → 结果回传 → 原路返回 → IoT 设备(欧洲)
关键特征:
网关容灾:设备自动切换至欧洲网关,数据经跨境寻址路由至中国归属网关,经 HTTP 透传由业务服务处理。重要数据实时推送用户,非核心数据归档后原路返回设备。
-
场景四:用户与设备同时异地接入(设备和用户归属中国,用户出差美国,设备欧洲接入)
1. 下行控制链路(用户 App 下发设备指令)
用户 App(美国)→ 业务网关(美国)→ HTTP → 本地调度服务 → 数据中心(跨境寻址路由)→ 用户账号归属区域业务网关(中国)→ 业务设备服务处理(请求挂起阻塞,发现设备异地上线)→ HTTP → 本地调度服务 → 数据中心(跨境寻址路由)→ 设备网关(欧洲)→ IoT 设备 → 结果回传 → 原路返回 → 用户 App(美国)
2. 上行上报链路(设备主动上报状态、数据、告警): 与场景三上行上报链路一致。
关键特征:
-
双重跨境寻址:下行指令需经过两次跨境路由——先根据用户账号归属(中国),再根据设备实际接入点(欧洲)
-
归属网关是唯一枢纽:无论用户和设备在哪里,账号归属网关(中国)始终是逻辑中心,所有请求必须经它中转
-
路径最长,延迟最高:相比场景二(单方异地)增加一次跨境往返,是四种场景中通信路径最长的
-
设计根源:欧洲数据不出欧洲
上述四种场景的复杂度,根源在于一条硬性约束:欧洲用户和设备的数据不能离开欧洲(GDPR / 数据本地化要求)。
跨云迁移主要难点
-
RocketMQ 内网 IP 问题
六年前部署时 Broker 配了内网 IP,导致跨云迁移后新环境无法直接访问旧 MQ 集群。 -
设备固化域名解析 IP
早期合作方未按规范开发,部分设备配网时将域名解析为 IP 并固化到本地缓存,导致迁移后仍直连旧网关。 -
APP 与设备跨云时空割裂
迁移过程中,用户 App 已切换至新云(GCP),但设备仍连接旧云(AWS),导致指令无法送达或响应错乱。 -
数据库连接池切换时的脏数据问题
迁移最后一步,将应用的数据源连接池从 AWS 数据库切换到 GCP 数据库。切换不是瞬间完成的——旧连接池还在处理未完成的事务,新连接池已经开始写入,极易产生脏数据。
一个人运维的困境: 没有团队兜底,压力巨大。 -
全球跨洲际路由调度难题
迁移涉及欧美双节点,设备、用户、归属网关分布在三大洲。切换时不仅要保证单节点内部一致,还要保证跨洲路由不中断。 -
迁移期间发现黑客攻击
迁移窗口期,系统同时处于新旧两套环境并行运行的状态,暴露面翻倍。就在这个时候,发现了异常的跨境请求——有人在试探跨洲路由的边界。
迁移结果
欧洲节点: 用户量较少,作为首个攻克目标。由于没有预演,过程曲折,各种意料之外的问题接踵而至,好在最后有惊无险。
北美节点: 全盘复用欧洲节点的迁移流程,过程顺利。
结语: 7年前亲手创建,7年后亲手删除

上图为迁移最后一步:删除 AWS 欧美节点的服务器。Zabbix agent 不可用的告警,是这些机器关机前的最后心跳。
更多推荐
所有评论(0)