ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

SLB+ECS+OSS+RDS组合迁移实战:从单机到高可用架构

SLB+ECS+OSS+RDS组合迁移实战:从单机到高可用架构

简介:一份讲解阿里云SLB、ECS、OSS、RDS四大核心服务及系统数据迁移的Word文档,面向云架构师、运维工程师及有迁移需求的中高级技术人员,旨在帮助读者快速掌握负载均衡、对象存储、关系型数据库等组件的关键概念与协同用法。包体共1个docx文件,压缩后约1.78MB,体积精简、内容密度高,目录按服务模块分章节展开,便于按需定位阅读。当前已有778人学习/下载,得到不少实践者关注。文档并未停留在概念罗列,而是从OSS的桶、对象、存储类型,RDS的实例、数据库、账户权限,到SLB的监听器、后端服务器、会话保持、健康检查等核心机制均有系统梳理;后段还专门覆盖SLB产品优势、高可用架构、功能特性与应用场景,并给出快速入门与证书管理指引,可帮助读者在阿里云迁移与架构设计场景中形成清晰的操作思路。

1. 先认清 SLB-ECS-OSS-RDS 这套组合在解决什么问题

如果只用一个词形容我第一次做 SLB、ECS、OSS、RDS 这套组合迁移的感受,那就是:拆家。原来所有东西都堆在一台服务器上——图片放在应用目录里,MySQL 跑在同一台机器上,Nginx、后端服务、数据库挤作一团,DNS 直指这台机器的公网 IP。平时看着挺稳,直到某次磁盘故障,恢复数据花了一整天,才意识到单点架构根本没有后悔药。这套迁移方案要做的就一件事:把静态资源拆给 OSS,把数据库拆给 RDS,把应用拆给 ECS,最后在入口加一层 SLB 做流量分发和故障转移。适合正在做系统上云、自建机房转托管服务、或者想把单机架构改成可水平扩展的团队。下面按实际迁移顺序讲,先规划,再搬数据,最后接负载均衡和验证。

2. 迁移架构与服务规划:顺序对了,坑少一半

2.1 一张对照表理清迁移前后架构

动手迁移前,先别急着买实例、配环境。我习惯先画一张迁移前后的对照表,把每个系统组件落在哪一层、先迁什么后迁什么定清楚。顺序不对,后面每一步都在给自己埋雷。

系统组件迁移前迁移后迁移顺序
静态图片/文件资源应用服务器本地目录,HTTP 直连访问OSS Bucket,走对象存储 URL第 1 步
MySQL 数据库自建 MySQL,与应用同机RDS MySQL,独立实例第 2 步
应用服务单机多服务混合部署ECS 按服务拆分,至少数据盘独立第 3 步
流量入口DNS 直连服务器 IP,无故障转移SLB 负载均衡 + 健康检查第 4 步

这个顺序的逻辑很直接:静态资源无状态,迁移失败最多是图片 URL 暂时不可用,回滚成本最低,适合拿来练手;数据库迁移需要停机窗口,而且必须先于应用迁,这样后面部署应用时才能把连接串直接指到 RDS 内网地址;应用最后迁,迁完才开始处理连接串、依赖库这些真正麻烦的事;SLB 一定放最后,靠健康检查和权重切换实现不停机接入。反过来先接 SLB 再迁后端,等于在系统还没准备好的时候就把流量暴露在负载均衡后面,出问题的波及面直接翻倍。

2.2 ECS 服务器规划:规格、磁盘与地域

服务器规划这块,我的经验是:规格往够用偏上选,磁盘一定要把系统盘和数据盘分开。老系统单机 4 核 8G 能扛住的业务,新环境起步同样给 4 核 8G 一般没问题,但别买突发性能实例跑长时间高负载,CPU 积分耗尽后性能掉得让人怀疑人生。系统盘 40G 起步,数据盘单独挂一块,日志、临时文件、上传目录都放数据盘,以后扩容不用动系统盘。

地域选择是常被忽略的点。ECS、RDS、OSS 三个服务必须选同一个地域,原因很实在:同地域的云产品之间走内网地址互通,不计公网流量费,延迟也低一个量级。我见过有人 ECS 在杭州、RDS 在上海,应用连数据库走公网,慢不说,流量费用一个月下来够吃几顿好的。迁移前先在控制台把这几个实例的地域对齐,后面所有内网连接串都依赖这个前提。

安全组的规划同样要提前做。老环境通常是一台机器一把梭,安全组基本等于没有;新环境至少按三层来放开:对外入口只放 80/443,后端服务端口只在安全组内网互通,SSH 管理端口限定办公网来源 IP。

方向协议/端口来源用途
入方向TCP 80、4430.0.0.0/0对外 Web 服务 / SLB 回源
入方向TCP 22办公网 IPSSH 管理
入方向TCP 8080、8081 等安全组内互访后端服务间调用

注意:如果是公网 SLB,后端 ECS 安全组不需要专门对 SLB 放行额外端口,但必须保证 SLB 能访问到后端服务的监听端口,否则健康检查永远不通过,这个坑后面第 5 章会细说。

2.3 基础环境初始化:JDK、Nginx、Redis、webp 依赖

服务器初始化阶段,先把通用依赖装齐。我这套老系统是典型的 Java 技术栈,所以环境里必须有 JDK、Nginx、Redis,还有一个特别容易漏的 webp 依赖——图片处理接口靠它做格式转换,漏了后面必然翻车。

# JDK 用 1.8,老系统几乎都是 Java 8,别图新鲜升 11/17,依赖库会教你做人 yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel

java-1.8.0-openjdk 是运行环境,-devel 包提供 javac 和 tools.jar。很多老项目的打包脚本、启动脚本都会用到 javac,只装 JRE 到后面编译或热部署时会报找不到 javac,白白折腾一轮。装完顺手把环境变量固化到 profile 里:

cat >> /etc/profile.d/java.sh <<'EOF' export JAVA_HOME=/usr/lib/jvm/java-1.8.0 export PATH=$PATH:$JAVA_HOME/bin EOF source /etc/profile.d/java.sh java -version

JAVA_HOME 的具体路径在不同发行版上有差异,CentOS 7 的 OpenJDK 一般在 /usr/lib/jvm/java-1.8.0,Debian 系大概率是 /usr/lib/jvm/java-8-openjdk-amd64。装完先跑一次 java -version 确认,别急着往下走。

# Nginx 做前端入口和反向代理 yum install -y nginx systemctl enable --now nginx # Redis 做缓存或会话保持 yum install -y redis # 修改 /etc/redis.conf:bind 内网IP,requirepass 设置密码,protected-mode 保持 yes systemctl enable --now redis # webp 依赖:图片处理接口的灵魂 yum install -y libwebp libwebp-devel libwebp-tools

Redis 的配置有三个关键点:bind 要绑定内网 IP,不能默认 127.0.0.1 或 0.0.0.0;必须设置 requirepass,否则内网里其他机器能直接连上来;protected-mode 保持 yes。webp 的 libwebp 和 libwebp-devel 一定要装全,有些精简源里没有 libwebp-tools,可以跳过,但缺了 devel 包,后面 Java 调 JNI 加载 so 库会直接报错。这一套装完,基础环境才算齐。

3. OSS 文件资源迁移:从 HTTP 路径搬到对象存储

3.1 创建 Bucket:地域、权限和存储类型一次定好

文件资源迁移到 OSS,第一步是创建 Bucket。Bucket 的配置属性在创建时就要想清楚,因为地域和 Bucket 名称创建后都无法修改,改名的成本等于把里面所有对象重新复制一遍,相当肉疼。

配置项取值建议理由
地域 Region与 ECS、RDS 同一地域内网访问免流量费,延迟低
访问权限 ACL迁移期选私有,切换后再改公有读避免迁移过程中资源泄露
存储类型标准存储 Standard图片访问频繁,低频/归档不适合热点读取
Bucket 名称全局唯一,小写字母、数字、短横线创建后不可修改,命名要一次到位

Bucket 命名规则比想象中严格:只能含小写字母、数字和短横线,必须以小写字母或数字开头和结尾,长度 3 到 63 字节。名称在整个 OSS 范围内全局唯一,创建后无法改名。

地域选择的核心逻辑在 Endpoint 上。同一个地域,外网和内网的访问域名不一样,以杭州为例:外网 Endpoint 是 oss-cn-hangzhou.aliyuncs.com,内网是 oss-cn-hangzhou-internal.aliyuncs.com。服务器在 ECS 上就用内网 Endpoint 访问,本地电脑调试才用外网。这个细节决定迁移速度和流量费用,我见过有人 ECS 访问 OSS 走外网域名,文件是能传,但慢且贵。

存储类型方面,默认选标准存储即可。低频访问和归档存储虽然单价便宜,但适合每月访问一两次甚至半年才动一次的数据。图片资源是高频读取,选低频只会让每次访问都产生额外费用。

3.2 配置 AccessKey 与 ossutil

权限配置是迁移前最容易松懈的环节。别直接拿主账号 AccessKey 去配工具——一旦泄露,整个账号下的资源全暴露。我一般用 RAM 子账号,只授 OSS 相关权限,比如 AliyunOSSFullAccess,用完可以随时吊销换新。

ossutil 是命令行迁移的主力工具。它的安装不复杂:下载对应架构的 ossutil 二进制,赋可执行权限,放到 /usr/local/bin,然后执行 config 交互式配置:

chmod +x ossutil64 sudo mv ossutil64 /usr/local/bin/ossutil ossutil config

config 命令会依次询问 Endpoint、AccessKey ID、AccessKey Secret 和 STS Token。没有 STS Token 直接回车跳过。Endoint 填哪个取决于你在哪台机器上跑:ECS 上填内网 Endpoint,本地填外网。配置完成后默认写入 ~/.ossutilconfig,后面所有命令都会读取这个配置文件。

这一步有个小坑:配置文件里的 AccessKey Secret 是明文存储的,服务器上如果有多人登录,注意这个文件的权限。我一般会 chmod 600 ~/.ossutilconfig,避免同机其他用户读走密钥。

3.3 批量迁移图片资源:一条命令反复跑

文件资源迁移的典型场景是:原来图片放在应用服务器的 web 目录下,通过 HTTP 路径访问。迁移脚本的核心思路是扫描本地目录,逐个上传到 OSS,目录结构原样保留在 Object Key 前缀下。

# 从原 Nginx 图片目录扫描,上传到 bucket 的 images 前缀下 find /data/www/images -type f | while read -r f; do rel="${f#/data/www/images/}" ossutil cp "$f" "oss://my-bucket/images/$rel" --update --parallel 10 done

这个脚本有几个关键参数。${f#前缀} 的作用是去掉本地路径前缀,把 /data/www/images/a/b.jpg 转成 a/b.jpg,作为 Object Key 拼在 images/ 后面,这样上传到 OSS 后目录结构和原来一致,业务代码里拼 URL 路径时改动最小。--update 参数表示源文件比目标文件新或目标不存在才上传,脚本中断后重新执行会跳过已传完的文件,迁移过程可以反复跑。--parallel 控制并发上传数,10 对大多数服务器够用,带宽充足的可以调到 20 到 30。这个脚本的设计重点在可重入性——传了一半断了,重跑一次就好,不用全量重来。

如果源文件以 HTTP URL 列表形式存在,场景略有不同,需要先落盘再上传:

cat url_list.txt | while read -r u; do name=$(basename "$u") curl -s -o "/tmp/migrate/$name" "$u" ossutil cp "/tmp/migrate/$name" "oss://my-bucket/files/$name" done

这里要注意临时目录空间要够大,如果文件总量有几十 G,/tmp 默认分区可能直接写满。我一般会单独建一个迁移用的临时目录,放到数据盘上,避免系统盘被占满。

3.4 权限验证与回源切换

批量上传完成后,别急着切流量。OSS 迁移最忌传完就改配置,至少要过一遍校验:在 ECS 上用 ossutil ls 列出 Bucket 里的对象,统计数量,和源目录的文件数做对比,再抽查几个大文件的大小和 Content-Length 是否一致。ossutil 的 ls 命令支持按前缀过滤,比如 ossutil ls oss://my-bucket/images/ 只看图片目录,统计数量很方便。

权限这块,迁移期间 Bucket 保持私有是安全的做法,但接下来验证阶段,业务代码要能从外网访问到图片。常见做法是先把 Bucket 权限改成公有读,或者只针对 images/ 前缀配置授权策略,不做全 Bucket 开放。如果后续要接 CDN,权限策略还要再调整。

切换阶段还要明确一个原则:OSS 不等于文件系统。OSS 是扁平的 Key-Value 结构,images/a.jpg 里的 / 只是 Key 字符串的一部分,不是目录层级。正因为这个特性,在 OSS 里做“重命名目录”这种操作代价极高,等于把所有带这个前缀的 Object 全部复制一遍。所以迁移前一定要确认 Object Key 的结构和原 URL 路径的对应关系,尽量保持一一映射。如果路径对不上,优先在业务代码或者 Nginx 层做映射转换,而不是去批量 rename Object。原目录在切换后保留 7 天左右再清理,万一有回源请求还能补救,也算给自己留一颗后悔药。

4. MySQL 数据迁移 RDS:用 DTS 做结构、全量、增量三步

4.1 迁移前检查:账号权限、binlog 与白名单

数据库迁移是整个迁移里最需要耐心的一步,因为涉及停机窗口和一致性。DTS(数据传输服务)是阿里云官方的迁移通道,支持结构迁移、全量迁移、增量迁移三种能力,实际操作前先做一轮前置检查,能省掉后面大量返工。

检查项要求说明
源库 binlog开启,且保留至少 24 小时增量迁移依赖 binlog,保留太短增量可能追不上
源库账号权限SELECT、REPLICATION SLAVE、REPLICATION CLIENT增量同步需要拉取 binlog 的权限
目标 RDS 账号读写权限结构迁移要建表,全量要导数据
表结构大表尽量有主键DTS 预检查会警告无主键表,影响同步性能
白名单放行 DTS 服务器 IP 段DTS 控制台创建任务时会提示具体 IP 段

源库账号权限这块,最容易漏的是 REPLICATION SLAVE 和 REPLICATION CLIENT。只给 SELECT,结构迁移和全量迁移能过,但增量迁移一启动就报权限不足,任务卡在初始化阶段不动,很不显眼。binlog 保留时长同样关键,如果 binlog 只保留 1 小时,而全量迁移跑了两三小时,等全量结束去追增量时,源库 binlog 可能已经清掉了,任务直接失败。

RDS 白名单的处理方式是:在 RDS 控制台的白名单设置里,临时添加 DTS 服务所在 IP 段。DTS 任务创建后会给出具体的 IP 清单,把它们加进去,迁移完成后再移除,不要图省事直接放行 0.0.0.0/0。

费用这块提前说明白:DTS 增量迁移在任务运行期间持续计费,从全量完成到业务切换这段观察期,增量链路一直挂着,费用也在累加。所以切换完成、确认业务稳定后,一定要去控制台手动结束迁移任务,不然一条空跑的链路会一直扣钱。

4.2 创建迁移任务:三种迁移类型的取舍

在 DTS 控制台创建迁移任务时,结构迁移、全量迁移、增量迁移三种类型需要一起选。结构迁移负责在目标库建表建索引,相当于把数据库的骨架搬过去;全量迁移搬运存量数据,是把血肉填进去;增量迁移同步迁移过程中源库产生的新写入,保证数据不丢。

实际操作步骤是:进入 DTS 控制台,创建迁移任务,源库信息填自建 MySQL 的连接地址、端口和账号;目标库选择 RDS 实例,实例 ID 会自动带出,不用手动填地址;迁移类型勾选“结构迁移 + 全量迁移 + 增量迁移”;迁移对象可以选整库,也可以按表粒度勾选;最后启动任务,等待预检查通过。

预检查阶段常见的红灯集中在这几类:源库 binlog 未开启、源库账号权限不足、迁移的大表没有主键、表之间有外键依赖。外键依赖是迁移 MySQL 老库时的高频问题,DTS 默认会处理部分依赖关系,但如果源库外键跨库引用,预检查基本过不了,需要先手动调整或拆分迁移对象。

增量迁移对 SQL 操作的支持范围有个预期管理:DML 的 INSERT、UPDATE、DELETE 都支持;DDL 部分支持,比如建表、加列这类常用操作能同步,但部分 ALTER TABLE 的复杂操作可能不同步或需要手动处理。迁移期间发布变更,DDL 尽量安排在源库低峰期执行,并在目标库确认结果。

4.3 业务切换与结束任务:从增量归零到切连接串

迁移任务跑到全量完成、增量延迟持续归零后,才进入切换阶段。切换的动作序列要提前拟定,按顺序执行,切忌跳跃:

# 1. 摘除应用写入口(停写或少写,具体按业务容忍度定) # 2. 在 DTS 控制台确认增量延迟为 0,稳定 3 到 5 分钟 # 3. 修改应用配置:jdbc 连接串改为 RDS 内网地址 # 4. 重启应用,观察启动日志确认连接成功 # 5. 跑一条业务写入验证读写正常 # 6. 确认无异常后,去 DTS 控制台结束迁移任务

增量延迟归零这个动作要反复确认。延迟跳动的数据源不止 binlog 解析,还包括目标库的写入性能,RDS 如果在全量导入阶段设置了更低的 IOPS 上限,增量同步速度也可能被拖慢。切换前我一般会在 DTS 控制台多观察几分钟,确认延迟稳定在 0,而不是偶尔跳到 0。

切换时机的选择也有讲究。业务低峰期是基本前提,但更重要的是应用本身能快速停止写入。如果业务有定时任务、消息队列消费这类后台写入,光停前端入口不够,这些后台写入会持续产生 binlog,增量延迟永远归不了零。我遇到过这种情况:前端流量停了,结果凌晨的定时任务还在跑,增量延迟就是压不下去,最后只能等任务窗口结束再切换。

切换完成后,源库不要立刻销毁,保留只读状态几天,方便异常时回滚。确认新环境稳定后,再决定清理源库数据,还是把它降级为备份。

4.4 迁移容易栽跟头的地方:时区、包大小、字符集

数据迁完之后,应用连上 RDS,最容易碰到几个“看着是数据问题,实际是参数问题”的坑。这三个参数建议在切换前就对齐:

参数检查位置风险描述
time_zone源库与 RDS 参数组不一致导致业务时间差 8 小时
character_set_server源库与 RDS 参数组不一致导致中文乱码
max_allowed_packetRDS 参数组过小导致大批量 SQL 报 packet too large
sql_modeRDS 参数组过严导致老 SQL 执行报错

时区问题最隐蔽。很多自建 MySQL 实例的 time_zone 是 SYSTEM,跟随操作系统时区;而 RDS 默认是 +08:00 或 UTC,如果业务代码用数据库时间函数生成时间戳,迁移后就会发现时间不对。RDS 控制台的参数组里可以直接改 time_zone,改成和源库一致再切换。

max_allowed_packet 的坑出现在跑大批量 INSERT 或导入 SQL 文件时,报 MySQL server has gone away 或 packet too large。RDS 默认值通常够用,但如果老系统有批量导入历史数据的操作,建议先调大到 64M 再切换。sql_mode 则需要对照源库的配置,老系统在宽松模式下能跑的 SQL,到严格模式下可能直接报错,尤其是零日期这种常见老数据。

5. 应用迁移到 ECS 与 SLB 接入:常见问题排查

5.1 webp 依赖缺失,图片接口批量 500

现象:应用迁到新 ECS 后,Web 服务启动正常,但访问图片处理、缩略图相关接口时大面积 500,后端日志里出现 libwebp 相关 so 文件加载失败或 Command not found。

原因:老服务器上曾经手动装过 webp 编解码库,但安装记录没人记。新服务器初始化时只装了 JDK 和 Nginx,漏掉了 libwebp。Java 服务调用 webp 转换时,要么走 JNI 加载本地 so 库,要么通过命令行调用 cwebp 工具,缺了哪个都会报错。

解决:

yum install -y libwebp libwebp-devel libwebp-tools # 如果系统的默认源里没有,需要编译安装 libwebp # 下载源码包后执行: ./configure --prefix=/usr/local make -j$(nproc) make install ldconfig

装完用 webpinfo 或 cwebp -version 验证一下命令可用。这个问题的根源在迁移前的依赖盘点没做全。我现在的习惯是:迁移前在源服务器上执行 ldconfig -p 和 rpm -qa 把动态库和软件包清单导出来,对照新环境逐项核对,而不是等接口报 500 再回来补装。

5.2 端口打架:Apache 与 Nginx 抢占监听

现象:Nginx 启动正常,Apache 却起不来,报 Address already in use;或者 Nginx 反向代理访问后端时,打到错误的服务上,接口返回的内容完全不对。

原因:老系统里 Apache 长期监听 80 端口,新环境加装了 Nginx 后,两个服务都要占 80,系统起来一个另一个就挂。更深一层的原因是端口规划没在迁移前做,后端有 web 后台、APP 服务等多个 Java 进程,端口全凭启动脚本里随手写的,换到新环境就容易冲突。

解决:统一规划端口,把对外入口和对内服务彻底分开。Nginx 固定占用 80/443 对外,Apache 改到 8080 或 8010,Java 后台服务按业务分端口,如 8081 给 web 后台、8082 给 APP 服务,MapzoneServer 单独占一个端口,写入运维文档。

# /etc/httpd/conf/httpd.conf Listen 8080 # /etc/nginx/conf.d/default.conf server { listen 80; location /api/ { proxy_pass http://127.0.0.1:8080; } }

配置文件改完后,systemctl restart httpd nginx,再用 ss -lntp 确认端口监听情况。端口规划这种事先做能避免的事,比事后排查省心太多——我在这上面翻过车,后来所有迁移项目都先出端口分配表再部署。

5.3 SLB 健康检查误判:探活探了个寂寞

现象:SLB 后挂了两台 ECS,其中一台后端应用已经挂了,但 SLB 就是不摘除它,用户请求偶尔还会打到坏节点上,出现部分请求超时;另一种情况是后端服务明明正常,SLB 却一直显示健康检查失败,节点始终是红色。

原因:健康检查协议选的是 TCP,只探测端口通不通。Nginx 或 Apache 还在监听端口,但后端的 Java 服务已经僵死,TCP 探测结果自然是通的,SLB 认为节点健康,流量继续分发。反向的问题则是选了错误的检查路径,后端根本没有这个 URL,返回 404,SLB 判定不健康,可业务实际是好的。

解决:健康检查改用 HTTP 协议,配一个后端真正实现的健康检查接口,同时把超时、间隔、阈值调到合理值。

配置项建议值说明
健康检查协议HTTP比 TCP 更能反映业务可用性
健康检查路径/healthz后端必须实现该接口并返回 200
响应超时3 秒后端响应过慢会误判为不健康
健康检查间隔5 秒太频繁会给后端加压力
健康阈值2 次连续成功 2 次判定健康
不健康阈值3 次连续失败 3 次判定异常并摘除

后端实现的 /healthz 接口有几个设计要点:返回要快,不要查数据库做复杂校验,否则健康检查请求本身会把服务拖垮;只反映当前进程是否可用即可,进程活着就返回 200。SLB 控制台配置监听时,后端服务器组里加两台 ECS,权重默认 100 即可,如果两台机器规格不同,按规格比例调权重更合理。

SLB 的完整接入链路是:控制台创建负载均衡实例(地域选 ECS 同地域,类型选公网)→ 配置监听(前端协议 HTTP/HTTPS,端口 80/443)→ 添加后端服务器组(两台 ECS,权重分配)→ 配置健康检查 → 在 DNS 处解析一个 A 记录指向 SLB 的公网 IP。域名解析这步,很多团队会漏,导致 SLB 配了半天,用户还是解析到老服务器 IP 上,等于白接。

5.4 数据库连接串迁移后还是旧 IP

现象:RDS 迁移完成,应用也重新部署了,但业务一直报数据库连接失败,日志里显示的连接地址还是自建 MySQL 的老 IP。

原因:配置文件改了,但代码或打包产物里硬编码了旧数据库地址;或者项目用配置中心下发配置,配置文件里改完,配置中心还有一份旧值,应用启动时读取的是配置中心那份。

解决:切换前全盘扫描硬编码的旧 IP,别只查配置文件。

grep -r "192.168.1.10" /opt/apps/ --include="*.yml" --include="*.properties" --include="*.java" --include="*.xml"

把旧 IP 换成实际源库地址做一次全量搜索,发现硬编码直接改掉或改为从配置读取。部署完成后,检查应用日志里实际生效的数据库连接串是不是已经是 RDS 内网地址。我一般在启动脚本里加一行 echo,把 DB_URL 打印到启动日志里,启动后看一眼日志就能确认是否切干净,省得每次靠猜。

6. 装完怎么验证:从静态资源到负载均衡全链路

迁移部署完成不等于事情结束,真正的考验是验证环节。我每次迁移完都会强制走一遍全链路验证,从外到内,一层层确认,而不是只看看控制台显示“运行中”就收工。

先验证静态资源链路。从外网访问一个迁移后的图片 URL,用 curl -I 看响应头,确认能回到 OSS,响应头里带 x-oss-request-id 基本可以判断请求确实落在了 OSS 上。同时对比原 URL 和新 URL 的 Content-Length,文件大小一致,说明数据完整。

再验证数据库链路。在应用服务器上用 mysql 客户端连接 RDS 内网地址,注意是在 ECS 上连,用外网地址测不出内网链路通不通。执行 SELECT 1 确认基础连通性,再查一张业务表确认数据完整,最后可以做一次事务写入并回滚,验证写权限正常。

接着验证负载均衡链路。SLB 控制台里确认两台后端 ECS 的健康状态都是绿色,然后手动停掉一台 ECS 上的后端服务,从外网连续访问 SLB 域名,请求应该全部落到另一台正常节点,业务不掉线。恢复服务后,等健康检查阈值通过,节点自动回切到绿色。这个过程验证的是 SLB 摘除和恢复能力。

最后用一条命令做端到端验证:

curl -s -o /dev/null -w "HTTP %{http_code} | 总耗时 %{time_total}s\n" http://your-domain/healthz

返回 200 且耗时正常,说明域名解析到 SLB、SLB 转发到 ECS、应用健康检查接口返回成功,整条链路是通的。数据库和 OSS 的验证已经在前面单独做过,这条命令只验证链路,但它是每次变更后最值得跑的一步。

从那以后我每次迁移完,不管时间多紧,都把这条链路从外到内走一遍:域名到 SLB、SLB 到 ECS、应用连 RDS、静态资源回 OSS。流量调度和数据回源这两层,最容易在第二天早上被用户发现问题。希望这份记录能帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进