☰
用SLB-ECS-OSS-RDS四件套完成存量系统上云:迁移步骤、选型与避坑全解析
2026/9/30 11:44:20 网站建设 项目流程

简介:围绕阿里云核心云产品,这份docx系统梳理SLB负载均衡、ECS云服务器、OSS对象存储与RDS关系型数据库的基础概念及协同应用,并重点落到系统数据迁移场景。内容按服务模块展开,涵盖OSS的Bucket与Object、存储类型、上传下载及管理方式,RDS的实例、数据库、账户权限、备份恢复与迁移功能,SLB的监听器、后端服务器、会话保持、健康检查及产品架构与高可用方案。目录清晰,适合刚接触阿里云或需要规划数据迁移的运维与开发人员作为入门速查手册。资源包内含1个docx文档,体积约1.78MB,虽以文字讲解为主,但结构完整、层级分明,方便按章节查阅。该资源已有776人学习下载,能够为读者提供从单服务理解到组合架构设计的参考路径,是一份实用的云资源与迁移学习资料。

1. 阿里云SLB-ECS-OSS-RDS这套组合,到底是给什么系统准备的

如果你手里的业务系统还是老式单机部署——一台服务器既跑Web服务、又存数据库文件、静态图片也堆在本地磁盘——那么阿里云SLB-ECS-OSS-RDS这套组合,就是把这套老架构拆成四个能独立伸缩的层:ECS负责计算、SLB负责入口流量分发、RDS负责关系型数据、OSS负责静态文件和备份。最典型的场景是存量系统上云:原来部署在自建机房或旧云主机上的应用,要迁到阿里云并顺手把架构捋直。做这件事的人通常是一个运维或全栈开发,手里捏着一个能跑但不敢乱动的老系统,目标不是重写,而是平移,顺便把单点隐患拔掉。

这套方案真正解决的问题有三个:第一,把数据库从应用服务器里拆出来,避免磁盘写满或数据库进程占用过高CPU时整个Web服务跟着躺平;第二,把用户上传的图片、导出文件、日志这类对象数据从ECS本地盘挪到OSS,让ECS可以随时销毁重建而不丢数据;第三,用SLB在前面顶着,后续扩容只需往后端组里加ECS,不用改DNS。适合的人群是:系统还在用MySQL或PostgreSQL、有大量静态资源需要存储、对可用性有要求但不想直接上K8s的中小型团队。

2. 迁移前把资源规格定明白:SLB、ECS、OSS、RDS的选型与账单口径

2.1 四个产品在迁移里各自承担的角色边界

讲落地之前,先把四个服务的职责边界划清楚,否则后面操作时会反复纠结“这个东西到底该放哪”。

ECS是计算节点,跑你的应用进程。Spring Boot、Nginx、PHP-FPM、Python的Gunicorn,这些有状态的进程跑在ECS上。注意,这里说的是“有状态”是加了引号的——严格讲ECS本身应该尽量无状态,你的代码包要从构建机拉,日志要往外送,本地盘只放临时文件。但现实中存量系统迁移往往做不到这么干净,所以第一步先做到“应用代码和数据文件分离”。

SLB是流量入口,它不跑业务逻辑,只做四层或七层的转发。SLB把用户的请求按权重分发给后端的ECS,同时做健康检查——后端ECS的端口如果不响应,SLB会自动把它摘掉,不往这个节点转发新请求。对用户来说,访问的还是SLB那个固定IP或域名,后端换机器、加机器,用户无感知。

RDS是托管数据库,MySQL、PostgreSQL、SQL Server都有。你不需要自己装数据库软件、不用自己做主从复制、不用操心半夜磁盘满没满。迁移时把你的数据导入RDS实例,应用侧把数据库连接地址改成RDS的内网域名即可。RDS自动做每天备份,还能一键恢复到某个时间点。

OSS是对象存储,存的是“文件”:图片、附件、音视频、冷备数据、数据库备份文件。OSS的特点是无限容量、按量计费、自带CDN回源配合。跟ECS本地盘最大的区别是:ECS销毁或重置系统,OSS里的数据纹丝不动。

2.2 规格怎么定:先看QPS、再看存储量、最后看备份策略

规格选型容易犯的错是“按CPU核数拍脑袋”。我一般按这个顺序推算:

第一步,数清楚最大并发。打开现有Nginx的access.log,统计高峰时段每分钟请求数,乘以单请求平均耗时,得到需要一个ECS扛多少QPS。一个2核4G的ECS,跑一个优化过的Spring Boot或Go服务,大概能扛300~800 QPS,具体取决于业务逻辑是查缓存还是查库。如果你现在的日志显示高峰只有几十QPS,那2核4G起步足够了,不用一上来就买8核16G。

第二步,算数据库规格。RDS的性能瓶颈通常在连接数和IOPS。先看现有数据库的“最大连接数”配置,再看慢查询数量。如果现在MySQL的max_connections是200,日常使用率已经到70%,那买RDS时选择连接数不低于旧配置的规格。RDS的规格列表里每个档位都会标注最大连接数和IOPS上限,照着旧库的监控数据配对就行。

第三步,决定OSS的存储类型。存量图片、日志、备份选“低频访问”即可,单价便宜一半,只是读取时要收一点点数据取回费用。如果业务是用户高频访问图片,才选“标准存储”。这一步能省不少钱,尤其是历史图片几年才翻一次的场景。

SLB的规格唯一要关注的是“按固定带宽还是按流量计费”。如果业务流量平稳,选按带宽;流量有明显的波峰波谷,就选按使用流量,峰值时段多付一点,闲时少付。实例创建后,监听、后端权重、健康检查这些都可以随时调整,所以规格选错的后悔药很多,不用太紧张。

2.3 购买前的资源配置清单

购买之前先列一张表,相当于迁移项目的物料清单。这是我从几个项目里总结的通用模板,照着填空即可:

资源规格参考数量说明
ECS2核4G / 40G ESSD2台应用节点,先买两台组成SLB后端组
SLB按流量计费1个七层HTTP监听,后续升级HTTPS
RDSMySQL 8.0 / 2核4G / 100G1个主实例,不开只读
OSS Bucket标准 + 低频两个Bucket2个一个放热数据,一个放冷备
安全组放行80、443、221组ECS和RDS共用时要按IP白名单收敛

注意一个容易漏掉的东西:域名和SSL证书。如果业务是HTTPS访问,SLB上要挂证书。阿里云有免费证书可以申请,有效期三个月,到期需要手动续期——这件事我会在避坑章节展开,因为它是个经典翻车点。

3. ECS与SLB先行落地:把计算节点和流量入口从旧机房搬上阿里云

3.1 两种上云姿势:自定义镜像迁移 vs 新装系统重部署

老系统迁移到ECS,通常从二选一开始:到底是把旧服务器做成镜像直接导入,还是在新ECS上重新部署一遍环境?

我的建议是:如果旧服务器是CentOS 7或Ubuntu 18.04这类主流系统、且应用是通过systemd或supervisor管理的,优先做自定义镜像迁移。具体做法是把旧服务器的数据盘和系统盘分别打包,通过阿里云“导入镜像”功能上传到OSS,再基于这个镜像创建ECS。好处是应用运行环境、JDK版本、环境变量、Nginx配置全部原样带过去,不用重新踩一遍环境配置的坑。缺点是镜像里可能带着旧机器特有的驱动和垃圾文件,ECS启动后需要清理。

如果旧服务器系统太老、PHP版本过低、或者应用依赖的环境已经乱成一锅粥,那就老老实实新装系统重部署。虽然累一点,但环境干净,后续维护省心。判断标准很简单:旧服务器的装机文档还在不在。在的话,重部署;不在的话,镜像迁移后慢慢清理。

3.2 后端ECS的基本初始化:系统参数、JDK/Maven源、部署目录

新ECS开机后,第一件事不是装应用,而是把系统参数调成适合跑业务的样子。以下是我每次都会执行的一组命令:

# 关闭防火墙的SELinux,避免Nginx和Java进程出现诡异权限问题 setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config # 调整文件描述符上限,Java应用和Nginx高并发下默认1024不够用 echo '* soft nofile 655350 * hard nofile 655350' > /etc/security/limits.d/90-nofile.conf ulimit -n 655350 # 设置时区并同步时间,日志排查和定时任务都依赖它 timedatectl set-timezone Asia/Shanghai yum install -y ntpdate && ntpdate ntp.aliyun.com # 配置阿里云yum镜像源,安装依赖会快很多 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo yum clean all && yum makecache # 安装基础工具链 yum install -y vim wget lrzsz net-tools telnet

这段命令的逻辑分为四层:第一层关SELinux,因为SELinux开启状态下,Nginx反向代理到Java进程的回环连接可能被拦截,报错表现又极难排查;第二层调文件描述符,Java的Netty或Tomcat在连接数超过1024后会出现“Too many open files”,这个错在旧服务器上多半也遇到过;第三层统一时区和时间,数据库迁移和日志时间戳比对都需要两端时钟一致;第四层换阿里云镜像源,后续yum install的速度差一个量级。

如果是Java项目,还要顺带配置Maven的阿里云仓库镜像。在~/.m2/settings.xml里加上mirror节点,否则从中央仓库拉依赖在高峰期能卡到你怀疑网络:

<mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>

这里有个细节:阿里云Maven仓库有多个,public是聚合仓库,包含central和jcenter的代理,日常用它就够了。如果项目里用到spring-cloud-alibaba的早期版本,还要加一个https://maven.aliyun.com/repository/spring的镜像,否则某些旧版本依赖会拉不到。

3.3 配置SLB监听与后端服务器组:监听协议、权重、会话保持

ECS准备好两台之后,开始配置SLB。在控制台购买SLB实例时,地域要跟ECS一致,这样后端流量走内网,不额外产生公网流量费。实例创建完成后,进入“监听”页面添加监听,这里有几个参数必须说清楚:

第一是监听协议。业务是HTTP请求就选“HTTP”,不要选“TCP”,除非你明确知道自己在做什么。选HTTP的好处是SLB能识别URL路径,可以做按路径转发,也能拿到客户端真实IP放进X-Forwarded-For头。选TCP的话,SLB只是透传端口,后端的Nginx日志里看到的客户端IP全变成SLB的内网IP,排查问题时会很头疼。

第二是后端服务器组。把两台ECS加入后端组,端口填应用实际监听端口,比如Java应用是8080,Nginx是80。权重默认100就行,两台权重一致就是各分一半流量。如果你想让某一台先验证新版本,把它的权重临时调成10,另一台保持100,就能实现灰度引流。

第三是健康检查。SLB默认的健康检查路径是根路径/,如果应用的根路径返回404或直接连接拒绝,SLB就判定节点不健康,把所有流量都打到另一台上。如果你的应用根路径没有内容,要在健康检查配置里改成一个真实存在的接口路径,比如/health,后端应用也要实现这个接口并返回200。

第四是会话保持。如果业务登录态是存在Session里的、没有用Redis共享,那必须开启“会话保持”并设置超时时间。否则用户第一次请求打到A机器登录成功,刷新页面时被SLB转发到B机器,Session不存在,用户被强制重新登录。这个开关在SLB的监听配置里,默认是关闭的,忘记开的话迁移上线当天就会接到大量投诉。

4. OSS与RDS落地:数据迁移是这一步的重头戏

4.1 RDS:用mysqldump迁移MySQL数据,参数怎么给

RDS实例创建好之后,会拿到一个内网域名和端口,默认端口MySQL是3306。接下来要做的是把旧数据库的数据导入RDS。这里我不推荐在旧服务器上直接用mysqldump导完再上传,常见做法是先在RDS控制台建好目标数据库和账号,然后用一条命令从旧库直接导到RDS。

先确认两边的MySQL版本。如果旧库是5.7、RDS是8.0,语法兼容性问题不多,但MySQL 8.0默认的认证插件是caching_sha2_password,旧版本的应用驱动可能连不上——这个踩坑细节我在下一章展开。以下是迁移命令:

# 在旧服务器上执行,将全库导出并通过管道直接导入RDS mysqldump -h旧库IP -uroot -p'旧密码' \ --single-transaction --set-gtid-purged=OFF \ --default-character-set=utf8mb4 \ --databases business_db order_db | \ mysql -hRDS内网域名 -uroot -p'RDS密码' \ --default-character-set=utf8mb4

参数说明:--single-transaction是InnoDB表导出时开启一个一致快照,不影响线上业务写入;--set-gtid-purged=OFF是MySQL 5.6及以上才有的参数,如果不加,导出文件里会带上GTID信息,导入RDS时会报“GTID_PURGED can only be set when GTID_EXECUTED is empty”之类的错误;--default-character-set=utf8mb4必须两边都指定,否则遇到emoji或生僻字会转成乱码。

执行完这条管道,注意看终端最后有没有输出“completed”字样。另外强烈建议导入完成后在RDS上执行一遍表行数比对:

-- 在RDS上执行,与旧库的count结果逐表比对 SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema='business_db' ORDER BY table_name;

table_rows是估算值,但数量级对不上时能立刻暴露漏表或中断的问题。精确比对的方法是用COUNT(*)抽样几张核心表,不用全量。

4.2 OSS:用ossutil把存量静态文件迁到Bucket,并修正访问域名

数据迁移的另一半是静态文件。旧系统里用户上传的图片、附件、导出报表通常散落在ECS的/data目录、FTP服务器、甚至NFS挂载盘里。OSS迁移我用的是阿里云官方命令行工具ossutil,因为它支持增量同步和断点续传,针对动辄几十GB的附件目录很稳。

安装和迁移命令如下,在旧服务器上执行:

# 下载并配置ossutil,AK/SK在阿里云控制台RAM子账号里生成 curl -o ossutil https://gosspublic.alicdn.com/ossutil/1.7.19/ossutil-v1.7.19-linux-amd64.zip unzip ossutil && cd ossutil-v1.7.19-linux-amd64 ./ossutil config -e oss-cn-beijing.aliyuncs.com -i LTAI**** -k yourSecretKey # 把本地/data/upload目录全量同步到OSS的hot-bucket/upload路径下 ./ossutil cp -r -f /data/upload oss://hot-bucket/upload/ \ --parallel 8 --part-size 20MB --update --delete

参数含义:--parallel 8表示同时开8个线程并发上传,带宽够的话可以调高到16;--part-size 20MB是分片大小,超过这个阈值的文件会自动分片上传,支持失败后断点续传;--update是只上传本地比OSS更新的文件,跑第二遍时就是纯增量;--delete是把OSS里有但本地已删除的文件同步删掉,保证两边完全一致。这三个参数组合起来,相当于给迁移做了一个“可重复执行的同步脚本”,第一次全量,之后每次跑都是增量。

如果你的存量文件在MinIO或其他S3兼容存储里,ossutil也支持直接对接,写法是先把MinIO的桶通过s3协议的Endpoint配置成第三方源,再执行同样的cp命令。这个场景在存量项目里非常常见:公司内部早就用MinIO做了统一存储,上云时把MinIO桶里的对象搬迁到OSS,文件不用经手本地磁盘,直接服务端中转。

4.3 应用侧切换:配置文件里的地址从旧服务改成云上的Endpoint

数据进了RDS、文件进了OSS,最后一步是把应用配置改过来。这一步没有统一命令,因为每个应用的配置方式不一样,但有一个共同原则:把配置项集中管理,避免散落在代码里。

对于Java Spring Boot项目,常见做法是在application.properties里改如下内容:

# 数据库连接指向RDS的内网域名 spring.datasource.url=jdbc:mysql://rm-xxxxx.mysql.rds.aliyuncs.com:3306/business_db?useUnicode=true&characterEncoding=utf8mb4&useSSL=false spring.datasource.username=migration_user spring.datasource.password=newpassword # 文件访问路径改为OSS的Bucket公共读URL app.upload.url=https://hot-bucket.oss-cn-beijing.aliyuncs.com/upload/ app.upload.endpoint=oss-cn-beijing.aliyuncs.com app.upload.access-key-id=LTAI**** app.upload.access-key-secret=yourSecretKey

改完配置后,还要检查应用代码里是否有类似File file = new File("/data/upload/" + filename)这种直接写本地磁盘的代码。如果存在,必须改成把文件写入OSS,常见做法是引入aliyun-oss-sdk,用OSSClient的putObject方法替换本地文件写入。这一步是最容易被忽略的——很多人以为“文件路径改个URL就行”,结果应用启动正常、列表页正常,但新上传的文件直接写到ECS本地盘,过了几天ECS磁盘满了才发现问题。

5. 迁移避坑:从丢数据和流量中断里总结的排查清单

5.1 现象:SLB健康检查显示“后端异常”,但ECS上的服务明明在跑

迁移上线当天最常撞见的诡异问题:SLB实例的健康检查一直报红色,后端ECS显示“异常”,但登录ECS用curl访问本地端口却一切正常。

原因出在安全组上。SLB的健康检查请求来自阿里云内部的探测IP段,并不走公网。如果ECS安全组的入方向规则只放行了源IP为“0.0.0.0/0”的80端口,而没有放行SLB所在VPC的网段或SLB的健康检查IP,探测包就会被安全组拦截。于是出现“本机访问通、外网访问不通、SLB判定异常”的经典三体不一致。

解决方法是到ECS所属安全组里,为SLB监听端口增加一条来源为SLB所在VPC的网段放行规则。更简单的做法:在控制台的SLB实例详情页,找到“健康检查”的探测源IP段,把这个IP段加到安全组规则里。排查路径不复杂,但第一次遇到时很容易被“服务明明在跑”带偏方向。

5.2 现象:RDS数据迁移后,业务报“字段超长”或“字符集乱码”

数据导入RDS完成后,应用启动正常,但用户提交表单时报Data too long for column,或者历史数据里中文全部变成乱码。

原因有两个,分别对应两个现象。字段超长是因为旧库的字符集是utf8mb3(即常规的utf8),单字符最大3字节,而RDS新建库的默认字符集如果是utf8mb4,4字节字符能存但某些字段长度定义比如VARCHAR(200),在utf8mb4下实际能存的字数变少,字段定义没变的场景下就可能报超长。解决是在建库时明确指定字符集,并且在mysqldump导出时指定--default-character-set=utf8mb4,导入后逐字段检查超长数据,把VARCHAR长度要么调大、要么改成TEXT。

乱码的原因更隐蔽:旧库的实际字符集虽然是utf8,但客户端连接的字符集设置是latin1,历史数据在写入时就已经被错误转码存成了双重编码。这类“历史遗留脏数据”在迁移中不能靠参数解决,只能写脚本清洗。我的经验是迁移前先导出几条典型中文记录,用hex()函数看字节,判断是哪种编码再决定清洗方案,不要盲目把全库的字符集设置改掉。

5.3 现象:OSS文件上传后访问404,但Bucket列表里能看到对象

文件确实传上去了,控制台能看到对象,但通过URL访问时返回404。

这个问题的核心是Bucket权限设置和跨域规则。如果Bucket是“私有”权限,URL必须带签名才能访问;如果应用代码里没有对URL做签名拼接,那肯定404。解决方法是:如果这些静态文件是公开访问的,把Bucket权限改为“公共读”;如果某些文件涉及用户隐私必须私有,则不能改权限,需要应用代码用SDK生成带有效期的签名URL。

另一个新手坑是Bucket所属地域和Endpoint不一致。OSS的访问域名格式是bucketname.oss-cn-beijing.aliyuncs.com,如果你在控制台复制的是oss-cn-hangzhou的Endpoint,访问时也会失败。这个错看起来低级,但在切换配置的高压状态下非常容易发生。

5.4 现象:迁移当晚访问高峰,SLB把请求打到尚未就绪的节点

SLB的健康检查通过了,但用户反馈一部分请求超时。这个现象往往出现在更新应用代码或重启ECS之后。

原因在于ECS的“就绪”标准和SLB的“健康”标准不是一回事。健康检查只探测端口是否响应,但JVM可能还在加载类、连接池可能还没建立完成的阶段,端口虽然监听了,但请求在应用层排队超时。SLB按权重把流量打过来,这部分请求就直接掉进黑洞。

解决方法是不要用SLB默认的“检查间隔2秒、超时3秒、不健康阈值3次”参数跑生产。把检查间隔调到5秒、超时时间调到5秒、不健康阈值调到5次,并且把健康检查的URL指向一个真正能做“依赖检查”的接口,比如这个接口里轮询一次数据库连接池是否就绪。这样SLB的判定才跟业务真实可用状态对齐。

5.5 现象:SSL证书续期后网站打不开,证书过期没人记得

迁移到SLB之后,证书卸载工作从ECS转移到了SLB,这件事有利有弊。好处是后端ECS的Nginx不用再配置证书,坏处是证书到期前一个月,阿里云会发短信提醒,但如果你用的是一个三个月有效期的免费证书,到期日正好赶在项目忙碌期,很容易忽略。

解决方法是把证书续期这件事做成自动化或半自动化。常见做法是设置一个每月1号的定时任务,用脚本调阿里云API检查证书列表,如果发现剩余天数少于30天,就推送到钉钉或企业微信机器人。SSL证书续期本身在阿里云控制台点几次就能完成,但“没人记得去点”才是真正的坑。

6. 迁移后的验证技巧:用拨测与回退方案,把上线风险压到最低

迁移完成不代表上线完成,我一般会在切换DNS或修改SLB指向后,用一套固定的验证流程过一遍,耗时约一小时,但能拦下90%以上的低级失误。

第一类验证是连通性。登录一台不在阿里云VPC内的机器,用curl带-H "Host: 业务域名"访问SLB的公网IP,确认HTTP状态码是200、响应时间在预期范围内。这一步验证的是SLB转发链路是否完整,不受DNS缓存影响。

第二类验证是数据完整性。在RDS上抽查三张核心表,执行行数COUNT比对;在OSS上随机下载一个文件,比对MD5值,确认存储链路和文件内容都没问题。

第三类验证是业务链路。模拟一次完整的用户操作:注册或登录、上传一张图片、触发一次数据库写入、再读取这条记录。注意看应用日志里是否出现连接RDS或OSS的报错。

第四类验证是回退演练。把SLB的监听停掉,把流量切回旧服务器的入口,确认业务恢复。这不是真要做回退,而是确认回退路径是通的。没有回退路径的迁移是一场赌博,一旦线上出问题,你只能一边在监控台里挠头,一边被业务方盯着。

关于回退路径,有两个年份要记住:RDS的备份RDS已经自动做了,OSS数据有版本管理可以开,但ECS上的代码版本要自己在发布记录里留一份。我现在的习惯是每次迁移改动的配置文件,都拷贝一份带日期后缀的副本放在ECS的/tmp目录下,回退时直接复制回去就行。这个习惯帮我处理过不止一次上线后的突发状况。

最后还要提一句SSL证书。如果你在SLB上挂了证书,验证阶段务必用openssl s_client -connect 域名:443看一眼证书剩余有效期,并确认证书链完整。阿里云免费证书三个月过期一次,建议同时在日历上建一个提前两周的提醒。这套验证流程做完,整个迁移才算真正落了地。从单机到SLB-ECS-OSS-RDS的组合,改变的不仅是部署位置,更是遇到故障时还能不能睡个安稳觉——希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询