AWS→GCP:我准备好了MQ双写,却发现外网不通
引言
AWS、GCP 双活架构下,用户App切到 GCP,设备还在 AWS,通信问题如何解决?
本文针对这个问题,提出了两个可以实际落地的轻量级方案,希望能给你带来一丝灵感。
方案一:Redis会话和MQ双写
核心思路:
用 Redis 在 GCP 和 AWS 之间同步留存设备上线会话标识,用 MQ 双写实现“双写双消费”
当用户已迁入 GCP,设备仍停留在 AWS 时:
App 下发控制指令后,GCP 环境执行 MQ 双写。AWS 消费者收到 MQ 消息,通过比对 Redis 中的会话标识,发现设备属于自己,正常执行业务;GCP 消费者同样收到这条消息,比对后发现设备不在本地,直接空消费。
这种方式保留了原有的程序架构,同时打通了双环境的业务交互。
改造清单:
| 组件 | 改动方式 | 说明 |
|---|---|---|
| Redis 缓存模块 | 注入 RedisTemplateWrapper(第二个数据源),改写写入逻辑 | 向两个RedisTemplate同时写入会话标识 |
| MQ 生产者模块 | 注入 MessageSenderWrapper (第二个发送者),改写发送逻辑 | 向两个MessageSender同时发送消息 |
| 消费路由器 | 收到 MQ 消息时,从 Redis 读取设备会话标识 | 判断设备是否属于当前环境:属于当前环境则路由执行,不属于则空消费 |
为什么改动这么少
项目原有的 Redis 缓存、MQ 消息发送和消费路由都已高度模块化。我只需要新增两层包装类,就能做到业务代码零侵入,实现双向双写。路由器在消息处理源头加一层判断,根据会话标记决定路由或空消费。
优点: 三处改动合计不到一百行代码,全程不侵入原业务逻辑。双架构理论上独立运行,迁移窗口期出现意外问题的概率低。
方案确实可行,代码已经改完、本地简单模拟测试也通过了。但在欧洲节点实际部署时,我发现 GCP 环境无法连接 AWS 环境的 RocketMQ——Broker 绑的是内网 IP,外网不通,被迫放弃这个方案。
方案二:前置转发
核心思路很简单:不在MQ层解决问题,在网关层解决问题。
在 GCP 新环境网关前置一个转发服务,给 GCP 新环境上线的设备打上会话标记。当用户 App 接入 GCP 新环境、设备还在 AWS 旧环境时,转发服务发现会话标记为空或归属不一致,就把请求转发到旧环境网关。
流程解析:
- 写入标记: 改写新环境设备网关代码,当设备在 GCP 新环境上线时,按 KEY(设备编号)— VALUE(GCP 新环境标记) 写入缓存,供转发服务查询。
- 路由判断: 统计所有 App 下行控制设备的接口,统一交由转发服务管理。转发服务收到 App 请求时,根据设备编号查询 Redis 缓存中的标记,若发现设备不是在 GCP 新环境上线的,就把请求转发到 AWS 旧环境业务网关处理。
- 逐批迁移: 按批次把设备从旧环境迁到新环境,每迁一批,缓存中的标记就更新一批,转发服务自动将对应设备的流量切到新环境。
方案优势:
-
对旧环境:零入侵, 完全感知不到迁移在进行
-
对新环境:业务网关层前置一个转发服务, 配合几行设备网关代码改动
-
迁移完成后:转发服务和 AWS 旧环境服务直接下线,不留痕迹
方案约束:
-
零预演下的精确把控
迁移全程没有预演,所有操作都是第一次执行。前置转发依赖对设备编号的精确识别,但系统经过多年迭代,不同控制指令接口的设备偏好参数名称并不一致。转发服务需要统一识别这些标识,任何一个接口遗漏,都会导致指令下发失败。建议参考此方案时务必预演。我能跳过预演,是因为这套系统从0开始由我作为主程一直迭代至今。
-
跨系统迁移的复杂度
前置转发需要同时操作新旧两套系统,虽然对AWS 旧环境零入侵,对GCP 新环境代码入侵也很少,但流程复杂度远高于 Redis 和 MQ 双写方案。迁移过程中如果出现异常,面对的将不再是“修复一个系统”,而是“在两个系统之间找到断点”。预演无法完全覆盖这类问题,只能靠团队对系统架构的熟悉程度兜底。
方案可行,但危险性较高。我在迁移过程中也遇到了一些突发问题——部分问题在方案一身上不会发生。建议参考该方案时慎重评估,优先考虑 Redis 和 MQ 双写。
收尾
发现 MQ 外网不通时,已经接近第一周周三快下班了。必须在当周内完成欧洲节点的迁移,重启 MQ、部署第二个 Broker 都不现实。
最终依靠方案二完成了迁移。欧洲节点整个过程有惊无险,美国节点出了一个意想不到的问题,不过整体基本平稳度过。
下一篇讲述用户 App 和设备如何切流,以及切流过程中遇到的各种问题——方案二潜在的那些隐患、合作公司不按协议做的部分、黑客攻击……都留到那篇再讲。
更多推荐
所有评论(0)