ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

SLB、ECS、OSS、RDS四件套云上迁移实战笔记

SLB、ECS、OSS、RDS四件套云上迁移实战笔记

简介:文档围绕阿里云SLB、ECS、OSS、RDS四大核心服务及系统数据迁移展开,适合云运维、开发人员及准备上云的项目团队阅读。内容以目录方式系统梳理:先介绍OSS对象存储的Bucket、对象、存储类型与管理方式;再讲RDS关系型数据库的实例、数据库、账户及备份恢复;后重点展开SLB负载均衡的监听器、后端服务器、会话保持、健康检查、产品架构与应用场景,并串联系统迁移中多个服务的配合方法。除概念外,还涉及管理工具使用、常见操作与架构设计,并补充证书管理、健康检查等实用细节,覆盖从入门到落地的完整链路。全包为1个docx文件,大小约1.78MB,结构紧凑,便于按章查阅。目前已有778人学习下载,适合需要快速上手阿里云核心服务的中高级云运维与开发人员。

1. 拆一份把SLB、ECS、OSS、RDS串起来的迁移笔记:它能解决什么

搞云上迁移的工程师最怕的不是单个组件不会配,而是四个服务全都熟,却不知道先迁什么、后迁什么、哪个环节会卡住。这份笔记正好踩中了这个痛点——它不是官方文档的复制粘贴,而是一套带完整顺序的迁移实操:先把系统里的静态资源从HTTP目录挪到OSS,再把MySQL数据迁进RDS,接着把应用服务部署到ECS,最后用SLB把流量收口。整个过程有服务规划、有参数配置、有迁移后的验证和清理,适合正在做自建机房上云、或者打算把业务整体搬到云上的人直接照着走。后面几章会把每一步的命令、参数和踩过的坑按实际执行顺序拆开讲。

2. 云上四件套怎么选型与排序:先把资源和迁移顺序理清

2.1 四个服务在系统里分别扮演什么角色

OSS、RDS、ECS和SLB,这四个服务看名字都认识,但在一次完整迁移里各自承担的任务是完全不同层面的。OSS是对象存储,负责存放图片、音视频、附件这类非结构化数据,它的核心价值是海量、低成本、不占应用服务器磁盘;RDS是关系型数据库,负责MySQL这类结构化数据的存储和查询,迁移后不用再自己管主从、备份和监控;ECS是计算资源,跑应用代码和中间件,相当于原来那台物理服务器的替代品;SLB则是流量入口,把用户请求按策略分发到多台ECS上,顺带完成健康检查和故障摘除。

这套划分看起来简单,但迁移时必须先想清楚一件事:数据永远比代码难搬。代码错了可以重新部署,数据丢了没法重来。所以我的做法是先把OSS和RDS这两条数据链路打通,再谈ECS上的应用部署,最后用SLB把入口接上。

2.2 规格选择:这套系统适合什么配置

原文里没有给出具体的机器规格数字,但通过系统服务组成可以反推出来。这套系统包含了地图类服务模块、Web后台、APP移动端接口服务,还依赖Nginx、Redis、Apache、JDK环境。这种组合意味着CPU和内存都有硬需求,不能拿最低配的ECS硬扛。

我的选型思路是:ECS实例规格优先选通用型或计算型,4核8G起步,因为地图类服务模块通常有大量空间计算和坐标转换逻辑,CPU容易先打满;内存方面,Redis缓存和JVM堆内存要提前预留,2G内存的实例跑Java服务加Redis一定会频繁触发Swap,这是最常见的翻车点。带宽方面,如果文件资源已经迁到OSS,ECS的公网带宽只需要覆盖动态请求和应用API,5Mbps起步就够用;如果文件还留在ECS本地,带宽就要按峰值流量重新估算。

RDS的规格取决于MySQL的QPS和存储量。这套系统的数据量级如果以GB为单位,4核8G的MySQL实例已经够用;如果原库表数据量在百GB级别,建议直接选8核16G,给增量同步和后续业务高峰留出余量。存储类型选SSD云盘,IOPS比高效云盘高出一截,MySQL这类随机读写密集的引擎对IOPS非常敏感。

OSS的存储类型选择反而是最不需要纠结的一步。原文档明确列了标准、低频访问、归档三种存储类型,对应关系很直接:系统当前正在展示和访问的图片、用户上传的附件,走标准存储;半年以上的历史日志、已经不再访问的归档数据,走低频或归档存储。这里有一个经常被忽略的成本陷阱:低频访问类型的单价虽然低,但每次读取都要额外收数据取回费用,如果资源明明每天都被访问却选了低频,月底账单会比标准存储更贵。

服务核心角色选型要点
OSS静态资源存储热数据选标准,冷数据选低频/归档
RDS关系型数据库规格按QPS和存储量定,8G起步稳妥
ECS应用和中间件运行4核8G起步,注意内存和带宽余量
SLB流量入口和负载分发按业务域名和监听协议规划实例数

2.3 迁移顺序为什么是OSS、RDS、ECS、SLB

原文档的章节组织暗含了这套迁移顺序,我在实操中验证过这个顺序是合理的。先迁OSS是因为静态资源迁移和应用逻辑无关,文件上传完成后只需要把代码里的资源路径从本地地址换成OSS的访问域名即可,风险最低。再迁RDS是因为数据库迁移有全量加增量的窗口期,先把全量数据导入到RDS,再通过增量同步追平源库的写入,后面切应用时数据库已经是一条完整的新链路。接着迁ECS,把应用代码和环境依赖部署到新机器上,让应用直接连接RDS和OSS。最后配SLB,把流量从旧入口切到负载均衡上。这个顺序保证每一步都有明确的完成标准,不会出现在同一时间既要改代码又要导数据还要切流量的混乱局面。

2.4 内网Endpoint与外网Endpoint:一个低成本高收益的细节

OSS和RDS都提供内网访问域名,同一地域的ECS访问这些服务时走内网链路,不消耗公网流量,延迟也更低。原文档里明确提过,OSS的内网Endpoint就是对应的地域内网域名,RDS也提供内网连接地址。实际部署时,ECS上的应用代码一定要配置成内网Endpoint,否则一旦流量起来,公网流量费用会成为一个持续流血的成本项。判断配置对不对很简单:在ECS上ping一下配置的Endpoint域名,解析到10.x.x.x或100.x.x.x这类私网地址段就是内网,解析到公网IP就是配置错了。

这里还有一个容易忽略的点:Bucket创建时选了哪个地域,内网Endpoint就是哪个地域的域名。如果Bucket在华东某地域,ECS也在华东某地域,内网访问走通没有问题;但如果Bucket在A地域、ECS在B地域,内网链路就不存在了,只能走公网。所以创建Bucket之前,一定要先确认ECS和RDS的所在地域,尽量让所有服务落在同一个地域。

3. 系统文件资源迁OSS:批量上传、权限控制和回源兜底

3.1 迁移前的文件清点与目录规划

原文档在系统文件迁移这节提到了“迁移准备-准备网络访问图片资源”,这句话背后要做的事比看上去多。准备网络访问图片资源,第一步是把原来系统里通过HTTP对外提供访问的图片目录完整盘点出来,确认总大小、文件数量和目录结构。这一步不要省,因为OSS的Object Key设计直接决定后续代码改动量。

我一般会先在源服务器上跑一条统计命令,把文件总量和数量摸清楚:

du -sh /data/www/upload find /data/www/upload -type f | wc -l

du统计目录占用空间,find统计文件数量。这两个数字决定上传方式:几十GB以上就走命令行工具批量并发上传;几十MB级别的零散文件,直接图形化工具拖上去也能接受。文件数量多但单文件很小的情况要特别注意,比如大量几十KB的头像图片,这种场景的瓶颈不在总大小,而在每秒钟能处理多少个文件,并发参数要往上调。

目录结构也要在这个阶段定好。OSS的Bucket是扁平结构,本身没有目录概念,data/upload/2024/只是一个带斜杠的字符串前缀,但应用代码里的URL路径会直接映射到这个前缀。所以最好的做法是让Bucket里的Object Key和原服务器上的文件路径保持完全一致,例如原路径是/data/www/upload/images/logo.png,上传后Object Key就是upload/images/logo.png,这样代码里替换资源地址时只改域名前缀,不用改路径。

3.2 用命令行工具做全量上传

文件清点完成后,进入正式迁移。这个步骤原文档命名为“迁移实施”,核心工作就是把准备好的文件批量上传到OSS。标准做法是用官方的命令行工具,支持递归上传、并发控制和增量同步。

ossutil cp -r /data/www/upload oss://bucket-name/upload \ --parallel 8 \ --jobs 100 \ --update \ --delete

参数说明:-r表示递归上传整个目录;--parallel 8控制并发上传的任务数,8个并发是比较稳的起始值,机器性能好可以往上加到16;--jobs 100控制每个并发任务内部同时处理的文件数上限;--update表示只上传本地有而OSS没有的文件,以及大小不一致的文件,相当于增量同步;--delete会把OSS上存在但本地已经删掉的文件一并清理,保证两端一致。

这个命令第一次跑的时候是全量上传,后面再跑就是增量同步。整个上传过程要留意两个指标:一是上传速度是否稳定,二是错误文件数量。命令执行完后,用下面的统计命令确认结果:

ossutil ls oss://bucket-name/upload --stat

--stat参数会输出这个前缀下的文件总数和总大小,和第一步清点出来的数字做交叉比对,数量、大小都对上了,迁移才算完成。

3.3 权限模型:先私有后开白名单,而不是一刀切公开

上传完成后,进入原文档所说的“后续操作”环节。很多人到这里就急着把Bucket权限设成公共读,图省事,实际上这是安全上最大的坑。Bucket一旦公共读,所有Object都会暴露在公网,任何人都可以通过拼接URL访问你的数据,如果存在私有图片或用户上传的敏感文件,等同于直接裸奔。

我的习惯是Bucket ACL保持私有,然后通过RAM用户授权或者STS临时凭证让应用服务器访问;对于必须通过公网直接访问的图片资源,单独设置Object级的读写权限,而不是放宽整个Bucket。原文档里也专门提到了ACL的控制粒度,Bucket和Object是两套独立的权限体系,完全可以在Bucket私有的大前提下给指定Object开公共读。

多提一句Bucket命名规则,原文档写得清楚:只能包含小写字母、数字和短横线,必须以字母或数字开头结尾,3到63字节。这个命名在创建后无法修改,所以一旦定错,只能删了重建再传一遍,非常浪费时间。

3.4 上传后的验证与回源兜底

文件全部落到OSS后,还要解决一个兼容性问题:老的图片URL可能还被搜索引擎索引、被外部系统引用、或者被APP老版本的缓存记录。最稳妥的兜底方案是在ECS的Nginx里加一条回源规则:如果请求的路径在OSS上返回404,就回源到本地旧目录读取。这样即使有漏传的文件,用户访问时也不会直接看到图片裂开。

location /upload/ { proxy_pass https://bucket-name.oss-cn-xxxx-internal.aliyuncs.com/upload/; proxy_intercept_errors on; error_page 404 = @fallback; } location @fallback { alias /data/www/upload/; }

这段配置的含义是把/upload/路径的请求先转发给OSS内网Endpoint,如果OSS上找不到对应Object、返回404,就把请求转给本地旧目录兜底。proxy_intercept_errors on在这里是关键,不加这一行,Nginx会把404直接透传给客户端,不会走回源逻辑。回源兜底在切换初期很有用,可以等运行一段时间确认没有404后再关掉。

4. MySQL数据迁RDS:全量导入、增量同步与数据一致性校验

4.1 源库前置检查:binlog、字符集、账号权限

数据库迁移是最不能拍脑袋的部分。原文档里把“前提条件”和“注意事项”放在最前面,实操时确实如此。第一步是检查源MySQL的binlog配置,因为增量迁移依赖binlog来捕获源库的实时写入。

SHOW VARIABLES LIKE 'log_bin'; SHOW VARIABLES LIKE 'binlog_format'; SHOW VARIABLES LIKE 'binlog_row_image';

log_bin必须是ON,binlog_format必须是ROW,binlog_row_image最好是FULL。如果binlog没开,或者格式是默认的STATEMENT,增量迁移阶段会漏数据或者没法精确同步。这一步检查结果不满足,就先在源库把参数改掉并重启MySQL,不要往下走。字符集也要提前对齐,源库是utf8mb4,RDS实例也必须建utf8mb4,否则中文、emoji和一些生僻字在同步后会变成乱码。最后是账号权限,迁移账号至少要具备源库的SELECT权限,目标RDS账号要有目标库的读写权限。

4.2 全量数据导出与导入

前置检查通过后,先做全量迁移。全量阶段最常用的是先通过mysqldump把源库逻辑导出,再导入到RDS。导出时用--single-transaction,对InnoDB表开启一致性快照,不会锁表,业务可以继续写入。

mysqldump -h 源库地址 -u 迁移账号 -p \ --single-transaction \ --set-gtid-purged=OFF \ --routines \ --triggers \ --hex-blob \ db_name > full_dump.sql

参数说明:--set-gtid-purged=OFF避免导出文件带上源库的GTID执行记录,防止导入RDS时因GTID冲突报错;--routines和--triggers分别导出存储过程、函数和触发器,漏掉这两个参数,导出的库结构就不完整;--hex-blob把二进制字段按十六进制导出,避免乱码。业务量大的时候,mysqldump会占用源库一定IO资源,我一般放在业务低峰期执行。

导入到RDS用标准方式即可:

mysql -h RDS内网地址 -u 目标账号 -p db_name < full_dump.sql

导入后第一件事不是接着配增量,而是先抽查几张关键表的行数和最大主键,确认基础数据是对的,再进入增量阶段。

4.3 增量同步的配置与注意事项

全量导入完成时,源库的binlog已经推进了新的位点,此时需要启动增量同步把这些新写入追平。常见的做法是使用云上提供的数据迁移服务,原文档也单独列出了“增量数据迁移支持同步的SQL操作”和“数据库账号的权限要求”这两节,说明增量链路是整个RDS迁移的核心环节。

增量迁移链路启动后,重点监控同步延迟和错误日志。延迟数字在几百毫秒内是正常的;如果持续增长到几秒甚至几十秒,说明源库写入压力太大或迁移账号权限不足。这里有一条血泪经验:源库的binlog保留时间要提前调大。默认保留两天,如果全量导入和增量链路衔接期间源库binlog过期清理了,增量链路直接断开,只能删掉重来。

4.4 迁移完成后的校验方法

增量链路追平、源库和目标库数据一致后,先别急着切流量。我通常会做三层校验:

校验项方法通过标准
行数一致性对每张业务表分别SELECT COUNT(*)对比源库RDS行数完全相等
增量追平对比源库和目标库最新写入时间戳延迟低于可接受阈值
字段完整性抽查核心表的MAX(id)和最近更新时间与源库一致

行数和时间戳校验都通过后,再把应用代码里的数据库连接地址从源库改成RDS内网地址。这里有一点要注意:RDS的内网地址只能在VPC内访问,ECS如果不在同一个VPC或者没有开通内网互通,是连不上这个地址的。所以创建RDS时就要和ECS规划在同一个VPC,跨VPC之后处理起来会非常麻烦。

5. ECS应用部署与SLB负载均衡:环境安装、监听配置与避坑记录

5.1 ECS上按依赖顺序装好环境和应用服务

原文档在“系统应用服务迁移ECS”一节列出了完整的服务安装清单:JDK、Nginx、Redis、webp依赖环境、Apache、地图类服务模块、Web后台服务和APP移动端服务。这个安装顺序本身是有依赖关系的,不能乱跳。

我的执行顺序是:先装JDK,因为Java类服务模块和Web后台都依赖它,装完确认java -version正常再继续;然后装Nginx和Apache,这两个都是Web服务层,Nginx用来做入口转发和静态资源代理,Apache跑地图类服务的旧逻辑;接着装Redis,因为Web后台和APP端的会话缓存依赖Redis;再装webp图像处理依赖库,这个影响图片格式转换和压缩,漏了会导致后端处理webp图片时报错;最后部署各业务服务模块,并逐个确认端口监听了。

java -version nginx -t redis-cli ping systemctl status apache2

这套命令每执行一条就是一道检查关卡。nginx -t检查Nginx配置语法,redis-cli ping通不通返回PONG,Apache用systemctl看运行状态。任何一步失败就停下来解决,不要带着问题继续往下装。

5.2 SLB实例创建、后端挂载与监听配置

应用服务在ECS上跑通后,就进入SLB负载均衡的配置阶段。原文档把SLB的创建和配置分成“准备工作”、“创建负载均衡实例”、“配置负载均衡实例”和“域名解析”四步,实操时这四步的先后顺序不能乱。

准备阶段要先把后端ECS的端口和服务状态确定下来。比如Web后台服务的端口是8080,APP端API是8081,健康检查的URL是/healthz,这两个端口要在ECS的安全组里放行,并且只允许SLB所在的安全组访问。控制台创建SLB实例时,地域要和ECS在同一地域,实例类型按业务选择,公网+私网组合型适合绝大多数Web业务。

监听配置是整个SLB接入里最核心的一步,参数要按业务协议填准确:

配置项推荐值说明
监听协议HTTP / HTTPSWeb系统建议直接上HTTPS,证书提前上传
监听端口80 / 443对应用户访问入口
后端端口8080 / 8081对应ECS上实际服务端口
调度算法加权轮询后端两台ECS权重一致时轮询分发
健康检查协议HTTP用TCP检查只能探端口存活,探不到业务状态
健康检查路径/healthz后端服务必须返回2xx或3xx
会话保持按需开启需要登录态的Web应用建议开启,超时时间对齐应用session

这里要特别强调健康检查路径。很多人在SLB控制台图省事,把健康检查设成TCP 80端口检查,结果后端服务进程活着但业务逻辑卡死时,SLB照样把流量打过来,用户看到的就是页面无响应。用HTTP路径检查GET /healthz,让后端服务自己报告健康状态,才是真正有效的探活。

后端服务器组配置时,把两台ECS加进去,权重先保持默认100。加完后去SLB的服务器组页面观察健康检查状态,显示正常再继续。最后一步是做域名解析,把原来指向ECS公网IP的A记录改成指向SLB实例的公网IP。DNS生效前,先在本地电脑上改hosts做验证,确认解析到SLB后访问正常再推广到现网。

5.3 三个配置避坑:健康检查误判、会话保持过期、权重分配失效

这份资源里SLB部分的坑最值得单独写出来。第一个坑是健康检查误判。现象是某台ECS明明服务正常,却频繁被SLB标记为异常并摘除流量,把问题定位到健康检查配置才发现,检查路径指向的接口返回了302重定向,而SLB只认2xx和3xx之外的状态码为异常。解决方法是把健康检查路径指向一个只返回200的专用接口,不要指向带登录跳转的业务页面。

第二个坑是会话保持过期。现象是用户隔一段时间就莫名其妙退出登录,重新登录后过一会儿又掉。原因是SLB的会话保持超时时间设置得比应用自身的Session过期时间短,导致用户在应用Session还没失效时,负载均衡已经把同一用户的请求分发到了另一台后端ECS。解决方法是把SLB的会话保持超时设置为后端Session有效期的2到3倍,或者在后端引入Redis共享Session存储,让多台ECS之间无状态地切换。

第三个坑是权重分配失效。现象是新增的ECS已经配好权重,但观察流量始终打不到新机器。原因多半是新ECS没有加进后端服务器组对应的监听端口里,或者安全组没有放行SLB的健康检查来源IP。解决方法是逐个检查三层配置:安全组放行、后端端口监听、负载均衡后端组状态,三层都通流量才会过来。

6. 切换上线与回滚兜底:内网拨测、DNS切换、旧环境保留

6.1 切换前的完整检查清单

所有迁移工作做完,真正上线前要过的清单长这样:

检查项操作通过标准
OSS资源完整性对比统计上传前后文件总数和总大小完全一致
OSS回源兜底随机抽几个旧URL,确认OSS访问正常全部200
RDS数据一致性行数和最新时间戳对比完全一致
RDS增量延迟查看同步链路延迟监控秒级内
ECS应用服务逐个访问服务端口确认监听全部正常
SLB健康检查观察后端服务器状态显示正常
域名TTL把DNS解析记录的TTL临时调小60秒左右

提前调小TTL是上线阶段的关键操作。原方案里域名解析一条正常配置,生产切换时如果还保留默认TTL,DNS缓存可能需要几小时甚至一天才会全部刷新到新地址。我把TTL在切换前48小时调到60秒,等切换完成确认运行稳定后再调回默认值。这样做相当于给自己留了一粒后悔药,回滚时不用干等DNS缓存过期。

6.2 内网拨测和正式切换

正式切换前不要直接去改DNS,先做内网拨测。在ECS上模拟请求访问SLB,带上线上域名,确认完整链路是通的:

curl -H "Host: www.example.com" http://10.0.x.x/healthz

-H指定Host头,让SLB按域名路由到正确的监听器。10.0.x.x是SLB实例的内网IP地址。这一步能验证内网链路、监听转发和后端健康检查整套逻辑,同时不产生任何线上影响。如果返回200,说明链路没问题;如果超时或返回502,就逐段排查ECS安全组、SLB监听和后端服务状态。

内网拨测通过后,再操作域名解析把A记录从ECS的公网IP切换到SLB的公网IP。DNS切换之后,再跑一遍同样的curl命令,这次把地址改成SLB的公网IP,确认域名解析的最终访问路径是通的。

6.3 回滚与灰度验证

切换完成不代表马上销毁旧环境。我的习惯是把旧的ECS保留至少一个星期,RDS源库保留只读快照,OSS回源兜底规则也继续保留。一旦线上发现异常,回滚路径是从DNS层面把A记录改回旧ECS的IP,旧环境还能正常服务,整个过程控制在分钟级。

从那以后我每次做迁移,都强制把回滚方案写在切换之前,宁可回滚手段用不上,也不能出问题时手忙脚乱。这套SLB、ECS、OSS、RDS的迁移流程,完整走一遍大概需要两三个工作日,大头时间都花在数据校验和健康检查上,真正操作命令反而很快。希望这份整理好的迁移手记能帮到你,对照着做,少交点学费。

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

RELATED READING

延伸阅读

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