从裸机到云上四件套:OSS-RDS-ECS-SLB迁移实战与避坑指南

发布时间:2026/10/16 13:28:18
从裸机到云上四件套:OSS-RDS-ECS-SLB迁移实战与避坑指南
简介面向云计算架构师、运维工程师及系统迁移项目参与者此份Word文档系统梳理了阿里云四大核心服务SLB、ECS、OSS、RDS的功能特性与典型应用并重点剖析其在系统数据迁移中的协同方式。文档对OSS对象存储的桶、对象、存储类型RDS关系型数据库的实例、数据库、账户以及SLB负载均衡的监听器、后端服务器、会话保持等关键概念均有清晰讲解同时涵盖管理方式、常用功能与应用场景说明可作为上云迁移方案的参考手册。资源为单个docx文件体积约1.78MB便于下载后直接阅读或打印。目前已有778人学习下载具备较好的实践参考价值。读者可通过目录结构快速定位所需章节获得从理论认知到操作要点的完整知识闭环适合作为企业上云、数据迁移项目中的技术参考。1. 从一台裸 ECS 到四件套这套架构为什么值得照着搭一套跑了三年的地图业务系统图片和附件一直堆在自建服务器的磁盘目录里MySQL 也在同一台机器上跑入口就一个裸公网 IP。直到某天磁盘告警、数据库连接数打满、应用单点宕机那个晚上我决定做一次正经迁移文件上 OSS、数据库迁 RDS、应用迁到新 ECS、入口挂 SLB。这套 SLB-ECS-OSS-RDS 组合是中小团队上云最常见的四件套看起来是“照着控制台点几下”真动起手来踩坑点全在细节Endpoint 内网外网选错、增量迁移不会看追平状态、安全组挡住 SLB 健康检查、证书链不完整导致握手失败。这篇文章按我实际迁移的顺序来写OSS 迁文件、RDS 迁 MySQL、ECS 装应用、SLB 接流量最后一章给出完整的验证方法适合正准备迁移文件、数据库和服务器的开发者照着复现。2. OSS 迁移图片资源从 HTTP 目录搬进对象存储2.1 迁移前的 Bucket 规划与概念核对开始迁之前先把 OSS 的几个基础概念对齐不然后面配参数容易配错。OSS 里没有“目录”这个概念存储空间叫 Bucket文件叫 ObjectObject 由 Key 唯一标识Key 就是你在存储空间里看到的完整路径字符串。访问域名叫 Endpoint同一个地域内网和外网域名不同比如华东 1杭州地域的外网 Endpoint 是oss-cn-hangzhou.aliyuncs.com内网 Endpoint 是oss-cn-hangzhou-internal.aliyuncs.com从 ECS 访问 OSS 时用内网域名不走公网出口既快又不产生外网流量费用。AccessKey 是访问身份的凭证包括 AccessKeyId 和 AccessKeySecretSecret 一旦泄露等于把整个 Bucket 的读写权限交出去我一般会给专门的迁移账号开 RAM 子账号只授予 OSS 读写权限不用主账号的 AK。Bucket 有四个属性要提前定好地域、访问权限、存储类型、名称。地域在创建 Bucket 时指定之后不允许更改这个决策会直接影响后续所有内网访问的走向一定要选在 ECS 所在的同一个地域。Bucekt 名称在 OSS 范围内全局唯一只能包含小写字母、数字和短横线必须以小写字母或数字开头和结尾长度在 3 到 63 字节之间创建后无法修改名称取名要一次想清楚。存储类型按数据的热度选经常被访问的线上图片用标准存储半年以上不动的历史备份用低频访问或归档存储单价更低。OSS 术语含义Bucket存储空间所有 Object 的容器Object对象/文件由元信息、数据和 Key 组成Endpoint访问域名内外网后缀不同Region地域创建 Bucket 时指定后不可改AccessKeyAK身份验证凭证Secret 必须保密这五个概念里最容易翻车的是 Endpoint 和 Region。我见过有人把外网 Endpoint 配在 ECS 上跑批量同步几 TB 数据全走公网出口迁移还没结束流量账单先爆了。同一地域的 ECS 访问 OSS要在配置里写内网 Endpoint并且确认 ECS 和 Bucket 在同一地域不然内网域名解析不到请求还是会落到公网。2.2 安装 ossutil 并配置访问密钥迁移大批量文件我不推荐用控制台上传几千个小文件能点到手酸。OSS 官方提供了 ossutil 命令行工具Linux 和 Windows 都有编译好的二进制包从 OSS 工具页下载后解压就能用不需要安装依赖。下载解压后先执行交互式配置把 Endpoint、AccessKeyId、AccessKeySecret 填进去配置会写入当前用户的配置文件里后续命令自动读取# 解压工具包到 /usr/local/bin 目录 unzip ossutil-*-linux-amd64.zip -d /usr/local/bin chmod x /usr/local/bin/ossutil # 交互式配置依次输入 Endpoint、AccessKeyId、AccessKeySecret ossutil config配置时 Endpoint 这一项要填内网域名例如oss-cn-hangzhou-internal.aliyuncs.com这里不填 Bucket 所在 Region 的公开域名否则后面所有同步流量都会绕公网。AccessKeyId 和 AccessKeySecret 建议用 RAM 子账号的而不是主账号的子账号权限范围最小化只给目标 Bucket 的读写权限。如果迁移环境不止一台 ECS可以给每台机器配同一个子账号 AK也可以各自建一个方便事后审计。配置完成先跑一条只读命令验证身份是否可用# 列出指定 Bucket 下的对象验证 AK 和 Endpoint 配置是否生效 ossutil ls oss://your-bucket-name/能列出对象列表说明 Endpoint、AK、Bucket 三者对应关系正确。这一步能尽早暴露“AK 有权限但 Endpoint 配错地域”这类问题避免等大批量同步跑起来才发现文件全写进了别的 Region 的 Bucket。注意 Bucket 名称是全局唯一的你的 Bucket 名和我的不同target 路径里的 Bucket 名要替换成实际创建的。2.3 全量同步与增量同步文件资源放在源服务器/data/wwwroot/upload目录下同步到 OSS 用cp或sync子命令。首次迁全量用cp -r递归拷贝整个目录如果迁移窗口内线上还在持续写入新文件全量跑完后再用sync做增量追平把全量之后新增和更新的文件补上去# 全量同步将本地 upload 目录下的所有文件递归复制到 Bucket ossutil cp -r /data/wwwroot/upload oss://your-bucket-name/upload \ -e oss-cn-hangzhou-internal.aliyuncs.com # 增量追平只上传本地新增或内容有变化的文件 ossutil sync /data/wwwroot/upload oss://your-bucket-name/upload \ -e oss-cn-hangzhou-internal.aliyuncs.com --update-r表示递归处理子目录--update表示对比同名文件只同步本地新文件和时间戳更新的文件。如果你手头有超大文件可以加并发参数--jobs 4 --parallel 8提高传输效率--jobs控制并发任务数--parallel控制单文件的分片并发数具体值按 ECS 带宽调整。sync命令还有一个--delete参数作用是把目标 Bucket 里本地已经不存在的文件也删掉这个参数我强烈建议慎用尤其是在迁移核对阶段一旦误删远端文件没有后悔药除非你提前开启了版本控制。同步完成后要抽查对账最直接的方法是数文件数和比总大小# 对比本地文件数与 OSS 对象数是否一致 find /data/wwwroot/upload -type f | wc -l ossutil ls oss://your-bucket-name/upload/ | grep -c Object Number of # 随机抽几个目录深度的文件用 get 命令拉回来做 md5 对比 ossutil cp oss://your-bucket-name/upload/2024/06/example.jpg /tmp/check.jpg \ -e oss-cn-hangzhou-internal.aliyuncs.com md5sum /tmp/check.jpg /data/wwwroot/upload/2024/06/example.jpgOSS 上传完成后服务端会做冗余写入接口返回成功时数据已经有多份副本读取具备强一致性。但工具端的校验码比对更能发现传输过程中的静默损坏特别是海量小文件场景。OSS 本身支持同地域多个设施并发损坏时的数据冗余修复这部分靠产品自身保证我们做迁移只需要做端到端的文件级校验。2.4 应用侧路径替换与权限收敛文件迁到 OSS 之后程序里的访问路径要跟着改。原来的图片 URL 形如http://ip/upload/2024/06/example.jpgOSS 迁移后变成https://your-bucket-name.oss-cn-hangzhou.aliyuncs.com/upload/2024/06/example.jpg注意 Bucket 里upload/2024/06/example.jpg是一个完整的 Key不是多级目录程序拼接 URL 时直接拿 Key 拼域名即可。我通常会保留源服务器目录结构原样同步这样 Key 前缀和原来的 URI 路径一致程序只需要改域名连路径都不用动。权限这块我一般建议 Bucket 默认私有读写线上展示图片通过 CDN 回源或签名 URL 访问不要图省事直接设公共读。公共读的 Bucket 里一旦有敏感图片或备份文件被猜到 URL就是数据泄露。如果业务量不大、也没有 CDN最省事的做法是把需要公网访问的图片单独放一个 Bucket 或路径前缀对该前缀设置公共读数据库备份、日志这些敏感内容放私有 Bucket。最后还有一条 OSS 使用习惯要提醒不要把 OSS 映射成文件系统来用。OSS 的对象不支持原地修改改一个字节也要重新上传整个文件重命名目录意味着把所有相关 Key 都复制一遍成本极高。迁移之后程序里涉及文件的操作应该是“上传新文件、读取文件、删除文件”不要保留“打开文件追加写、重命名目录”这类逻辑这是 OSS 与本地文件系统最本质的差异。3. MySQL 数据迁 RDS全量加增量一次切干净3.1 迁移前检查版本、账号、binlog数据库迁移是整个搬迁里心理负担最重的一步因为它不允许试错。迁移前先把源库和目标 RDS 实例的版本对齐计划迁到 RDS for MySQL源库为自建 MySQL 5.7目标 RDS 也选 5.7版本差距越大预检查阶段报错的风险越高。移动云 RDS 实例要提前创建好设置好白名单白名单里要放行 DTS 迁移服务所在网段这一步在控制台发起迁移任务时会有明确提示如果你在 ECS 上自建了源库还要确认 ECS 安全组没有挡 DTS 的访问。源库需要准备一个迁移专用账号权限不是普通读写账号能覆盖的增量迁移要拉取源库的 binlog所以必须授权 REPLICATION 相关权限。下面这条 SQL 是我常用的授权模板-- 创建迁移专用账号并授予结构、全量、增量迁移所需权限 GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT, SHOW VIEW ON *.* TO migrate_user% IDENTIFIED BY Migrate2024; FLUSH PRIVILEGES;SELECT用于读取全量数据REPLICATION SLAVE和REPLICATION CLIENT用于增量同步拉取 binlog部分 RDS 实例还要求SHOW VIEW权限。授权范围用*.*是因为结构迁移可能涉及多个库如果你只迁一个库可以收紧到具体库名。生产环境里这个账号用完就要删不要长期留在源库上。数据迁移涉及增量同步时源库必须开启 binlog且 binlog 格式建议设置为 ROW 模式。很多自建 MySQL 默认没有开启 binlog预检查会直接亮红灯。修改my.cnf后需要重启 MySQL 服务这会带来一次业务中断所以确认 binlog 开关这件事要放在业务低峰期做或者提前在迁移评估阶段就确认清楚。另外字符集也要提前对齐源库表如果是 utf8mb4目标 RDS 参数组里的character_set_server也要设成 utf8mb4不然同步过去中文容易乱码这个坑在迁移后很难排查。3.2 控制台发起迁移任务迁移操作走数据传输服务 DTS在 RDS 控制台的“数据库迁移”入口进入。创建迁移任务时按顺序配置源库信息填自建 MySQL 的地址、端口、迁移账号和密码目标库选择已创建的 RDS 实例迁移类型勾选“结构迁移 全量数据迁移 增量数据迁移”这样一次任务就能完成表结构、存量数据和实时增量的同步不用分两段跑。迁移类型需要理解清楚再勾选结构迁移负责建表、建索引、存储过程等全量数据迁移是在任务启动时对源库打快照并复制已有数据增量数据迁移是持续读取源库 binlog把迁移任务启动之后的 INSERT、UPDATE、DELETE 操作同步过来。增量同步支持的 SQL 操作以常见 DML 为主部分 DDL 操作在同步过程中需要特别注意尽量在迁移窗口内不要在源库执行表结构变更否则容易导致结构不一致。预检查是启动任务前最后一道关口建议把每个检查项都读一遍再点“启动”。常见的红灯原因就这么几类源库 binlog 未开启、迁移账号权限不足、RDS 白名单未放行、源库和目标库的版本不兼容、无主键表数量过多。无主键表会导致增量同步性能变差预检查会有警告提示我一般选择在源库给这些表补上主键再迁而不是带着警告硬跑。任务启动后先去跑结构迁移和全量迁移这个阶段源库不需要停写DTS 会先拉一次快照。全量迁移完成之后任务自动进入增量同步阶段控制台会显示增量延迟时间延迟在 0 秒附近说明源库的 binlog 已经被实时追平。到这一步先别急着切换让增量同步任务多跑一会儿观察延迟稳定不反弹。3.3 切换与结束迁移任务切换的时机选择很关键我一般放在凌晨业务低谷。切换步骤是固定的先停应用对源库的写操作让源库停止变化观察 DTS 控制台增量延迟变为 0 秒接着把应用配置里的数据库连接串指向 RDS启动应用做连通性验证验证通过后再结束迁移任务。应用侧连接串切换是常规操作大部分 Java 应用的库连接配置都写在application.yml或application.properties里spring: datasource: url: jdbc:mysql://your-rds-instance.mysql.rds.aliyuncs.com:3306/appdb username: app_user password: App2024RDS 实例域名是控制台里分配的专有网络内网域名端口默认 3306从 ECS 访问走内网不需要公网 IP。注意切换后密码和账号要以 RDS 控制台创建的为准源库的账号密码带过去不起作用这一步最容易忽略导致应用启动时报Access denied for user。验证无误后回到 DTS 控制台结束迁移任务任务一旦结束增量同步链路就断了后续数据以 RDS 为准。结束任务之前我会把源库改成只读保留一周确认线上一切正常再把源库回收这是数据迁移的最后一层保险。4. ECS 应用环境部署JDK、Nginx、Redis、WebP 依赖与业务服务4.1 服务器规划与初始化应用服务迁移最忌讳“边装边想”先把服务清单列清楚。业务系统有五种服务要落到新 ECS 上Nginx 做入口反向代理Apache 承接一部分静态和动态请求Redis 做缓存MapzoneServer 是地图服务组件后台 web 服务和 APP 移动端服务是 Java 应用进程。对应端口规划如下服务端口说明Nginx80 / 443入口反向代理转发到后端服务Apache8080承接原有 httpd 逻辑Redis6379会话缓存、热点数据MapzoneServer9090地图业务组件web 后台服务8081Java 进程管理后台APP 移动端服务8082Java 进程移动端接口服务器初始化先做两件事更新系统软件源放行防火墙端口。用yum update -y把系统包更新到一致状态然后用firewall-cmd放行规划好的端口。这一步做完要立刻做一次端口连通自检因为新 ECS 默认安全组可能只放行了 22 端口后面服务全装好了才发现 80 端口从外网访问不通排查起来很被动。安全组和系统防火墙是两层独立的东西任何一层没放行端口都不通。我见过服务在 ECS 本机curl localhost正常但 SLB 健康检查持续失败的情况就是安全组只放行了 22没放行 8080。所以买完 ECS 第一件事是到控制台把规划端口全部加进安全组入方向再在操作系统内部配置防火墙两层都通才是真通。4.2 JDK 与 Nginx 安装JDK 版本按业务实际情况来这套系统的 Java 服务基于 JDK 8 开发我装的是 OpenJDK 8。用 yum 安装的好处是版本跟随系统源管理后续安全补丁升级方便不推荐手工解压 Oracle JDK既不好升级也不方便维护# 安装 OpenJDK 8 及开发包 yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel # 定位 java 真实安装路径 readlink -f $(which java) # 配置 JAVA_HOME 环境变量 echo export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk /etc/profile echo export PATH$PATH:$JAVA_HOME/bin /etc/profile source /etc/profile # 验证安装结果 java -versionreadlink -f这一步不能省因为 yum 安装的 java 命令是软链接指向真实的 JDK 目录版本升级后目录名会变写死路径容易踩雷。JAVA_HOME 配置在/etc/profile里全局生效Java 服务通过 systemd 启动时也会继承不需要在服务脚本里再配一遍。Nginx 直接用 yum 安装当前源里的版本足够稳定并且默认编译了--with-http_ssl_module模块后面配 HTTPS 证书不用重新编译# 安装 Nginx 并设置开机自启 yum install -y nginx systemctl enable --now nginx # 验证默认页面可访问 curl -I http://127.0.0.1/Nginx 在这里的角色是入口反向代理把 80 端口的请求转发给后端的 Java 服务。配置文件放在/etc/nginx/conf.d/下一个服务一个配置文件结构清晰server { listen 80; server_name your-domain.com; location / { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }proxy_pass指向 web 后台服务的端口X-Real-IP和X-Forwarded-For用来保留客户端真实 IP否则后端日志里全是 Nginx 本机地址排查问题会很痛苦。4.3 Redis 安装与 WebP 依赖Redis 在这套系统里承担缓存和会话存储。yum 安装的 Redis 默认配置绑定 127.0.0.1如果应用服务都在同一台 ECS 上保持默认监听回环地址是最安全的不用额外开防火墙端口。如果 Redis 要跨机器访问再把bind改成内网 IP 并设置requirepass# 安装 Redis 并设置开机自启 yum install -y redis systemctl enable --now redis # 配置访问密码避免未授权访问 sed -i s/^# requirepass foobared/requirepass Redis2024/ /etc/redis.conf systemctl restart redis # 验证密码认证是否生效 redis-cli -a Redis2024 pingRedis 未设置密码被扫描到就会沦为挖矿肉鸡这条线不能省。密码设置后要用redis-cli -a方式验证一次认证链路确认应用配置里的密码能正常连通。业务代码里 Redis 连接配置要和这里保持一致不然应用启动时连接超时日志里报错会指向“连接被拒绝”而不是密码错误容易误导排查方向。WebP 是图片处理依赖系统里需要把 JPG、PNG 转成 WebP 格式减小图片体积前提是环境里有 libwebp 库。优先用 yum 安装libwebp-devel如果当前源没有这个包就从官方仓库下载源码包编译安装# 优先尝试 yum 安装 yum install -y libwebp-devel # 如果源里没有源码编译安装 yum install -y gcc make autoconf libtool tar zxf libwebp-*.tar.gz cd libwebp-* ./configure --prefix/usr/local/libwebp --enable-libwebpdemux --enable-libwebpmux make -j$(nproc) make install源码编译有两个前置条件容易缺autoconf和libtool报configure脚本无法生成的错基本都是这两个工具没装。--enable-libwebpdemux和--enable-libwebpmux用来启用 WebP 的动图和拼接能力纯静态图片转换可以不加。编译完用pkg-config --modversion libwebp验证库文件是否被系统识别识别不到就把/usr/local/libwebp/lib/pkgconfig加入PKG_CONFIG_PATH。4.4 Apache 与业务服务部署Apache 在旧架构里承担了一部分静态资源服务和请求转发迁移到新环境并不是要把旧逻辑原样搬一遍而是先保证功能等价。yum 安装 httpd配置好 DocumentRoot 后启动作为 Nginx 后端的补充服务# 安装 Apache 并设置开机自启 yum install -y httpd systemctl enable --now httpd # 验证默认端口已监听 ss -lntp | grep :80Apache 和 Nginx 不能同时监听 80 端口生产环境里我把 Nginx 作为入口占用了 80Apache 改用 8080 端口由 Nginx 按路径转发。如果旧系统里 Apache 的职责只是静态文件服务Nginx 完全可以替代没必要额外保留 Apache但如果业务代码里有.htaccess规则依赖 Apache 特性就要保留直接平移端口。业务服务是三个 Java 进程MapzoneServer、web 后台服务、APP 移动端服务。程序文件从旧服务器打包拷贝过来用 rsync 推送到新 ECS 的/app目录# 在旧服务器上把程序目录推送到新 ECS rsync -avz --dry-run /app/ rootnew-ecs-ip:/app/--dry-run先跑一遍看传输清单确认没有误删风险再去掉这个参数。正式同步时我会加--excludelogs/*排除日志目录程序版本以新服务器干净部署为准旧日志排查时单独拉取不混进程序目录。Java 服务启动最简单的是nohup java -jar但这种方式服务器重启后不会自动拉起生产环境我习惯给每个服务写 systemd unit托管生命周期[Unit] Descriptionweb-backend service Afternetwork.target mysqld.service redis.service [Service] ExecStart/usr/bin/java -jar /app/web-backend/web-backend.jar --spring.profiles.activeprod WorkingDirectory/app/web-backend Restartalways RestartSec10 [Install] WantedBymulti-user.target三个服务各写一份 unitRestartalways保证进程异常退出后自动拉起RestartSec10避免崩溃循环时频繁重启。配置文件里三项必改数据库连接串换成 RDS 内网域名、Redis 密码、OSS 访问 Endpoint。改完用systemctl daemon-reload重载配置逐个systemctl start启动再用systemctl status确认进程状态同时盯住/app各服务的日志文件看启动过程中有没有连接异常。5. SLB 负载均衡接入与常见问题排查5.1 创建负载均衡实例与监听配置应用服务在 ECS 上稳定运行后开始接 SLB。先理清两件事SLB 实例要创建在 ECS 所在的同一个地域否则无法把该地域的 ECS 添加为后端服务器业务对外提供服务实例类型选公网只有内网互访需求才选私网实例。创建实例后第一件事不是急着加后端而是规划监听。这套系统的对外入口是 HTTP 和 HTTPS我创建了两个监听80 端口监听 HTTP 协议443 端口监听 HTTPS 协议HTTPS 监听需要提前上传证书。监听配置里几个关键参数按业务实际填配置项推荐值说明监听协议HTTP / HTTPS七层监听支持域名和路径转发监听端口80 / 443对外服务端口后端端口8081转发到 ECS 上的实际服务端口调度算法加权轮询按权重分配请求会话保持开启插入 Cookie保持用户会话健康检查开启检查后端服务存活性这里最容易搞混的是“后端端口”。监听端口是客户端访问的端口后端端口是 SLB 转发到 ECS 上的端口很多人在监听 80 时后端端口也填 80但 ECS 上实际监听 80 的是 NginxSLB 把请求转发过来后还要靠 Nginx 再转一次。如果 ECS 上的业务服务直接监听 8081监听 80 的后端端口就填 8081让 SLB 直接打到业务服务少一层转发。5.2 健康检查与后端状态健康检查决定了 SLB 会不会把请求发给某个后端 ECS。系统默认每隔两秒探测一次后端端口连续两次探测失败就把这台 ECS 标记为异常并自动摘除连续两次成功则恢复。这个机制在生产环境非常可靠但前提是探测的路径和端口要配得准。健康检查参数里有个细节如果监听是 HTTP 协议健康检查可以配置检查路径我建议填一个实际存在的静态资源路径比如/index.html而不是/。很多后端应用对/会返回 302 跳转SLB 的 2xx 判定把 302 视为健康但下一次探测 301 又可能被视为不健康状态反复横跳业务流量被随机摘除。后端 ECS 添加进负载均衡实例后权重默认 100两台机器就是五五分。如果一台机器配置高可以把权重调成 200 和 100让请求按 2:1 比例分配这是上线初期的保守策略等流量稳定后再调回均分。权重调成 0 的服务器会被立即摘除但还在健康检查范围内这个特性常被用来做发布窗口的流量切走比直接解绑实例方便得多。5.3 域名解析与删除注意SLB 创建时会分配一个公网 IP 和一个 CNAME 域名域名解析这一步不要直接解析到 IP而是用 CNAME 记录指向 SLB 的 CNAME 域名。原因很简单SLB 实例更换公网 IP 的场景存在但 CNAME 域名不变解析指向 CNAME 可以避免 IP 变化导致服务中断。在域名 DNS 控制台添加一条 CNAME 记录记录值填 SLB 控制台显示的实例 CNAME 地址。解析生效后再用nslookup your-domain.com确认 CNAME 链路解析正常此时访问域名就等于访问 SLB 实例。删除负载均衡实例的操作顺序和创建相反先在监听页面删除所有监听再在实例详情里解绑后端服务器最后释放实例。如果域名还解析着 CNAME释实例前记得先把 DNS 记录改掉不然流量打到已释放的 IP 上就是大片 503。5.4 踩坑记录五个反复出现的 SLB 连接问题第一条坑四层监听通但七层监听异常。现象是创建 TCP 监听后客户端能连接但换成 HTTP 监听后健康检查一直打红。原因是 ECS 上的服务没有监听在健康检查对应的端口或者安全组没放行 SLB 健康检查源 IP 网段。解决方法是先在本机用ss -lntp | grep 端口确认服务端口监听正常再到控制台安全组放行该端口和健康检查 IP 段。健康检查用的源 IP 属于阿里云特定网段文档里可以查到但更省事的做法是确认业务端口放行后用curl从 SLB 所在网络发起探测。第二条坑健康检查路径返回 301 导致状态抖动。现象是 SLB 面板上后端 ECS 状态在“正常”和“异常”之间来回切换流量时好时坏。原因是检查路径填了/后端 Nginx 把/301 跳转到/index.htmlSLB 对 3xx 响应码的判定不稳定。解决方法是把健康检查路径改成实际存在的/index.html同时要求后端对检查路径返回 2xx不要做任何跳转。第三条坑会话保持失效用户频繁掉登录。现象是用户访问时登录态丢失刷新页面就跳回登录页。原因是只配置了负载均衡没开会话保持请求被轮询到不同 ECS 上而业务会话又没有落到 Redis。解决方法是把监听协议换成 HTTP开启 cookie 保持模式插入 cookie 让 SLB 把同一用户的请求固定转发到同一台 ECS超时时间设 15 到 20 分钟。如果业务能接受我建议把会话数据统一放到 Redis不依赖 SLB 会话保持这样任意一台 ECS 宕机都不会丢会话。第四条坑HTTPS 证书上传后握手失败。现象是证书已上传监听端口 443 也显示正常但客户端报handshake failure。原因是证书链不完整只上传了域名证书没上传中间证书或者私钥带了密码。解决方法是重新上传证书内容要包含完整证书链私钥必须是无密码的 PEM 格式。上传后验证命令如下# 验证证书链是否完整、域名是否匹配 openssl s_client -connect your-domain.com:443 -servername your-domain.com输出里Verify return code: 0 (ok)表示证书链完整。如果报证书链不完整把中间证书内容拼接在域名证书后面再上传一次。第五条坑权重调 0 后服务没有完全摘除。现象是后端服务器权重设置为 0但仍有少量请求打到这台机器。原因是在权重调整前建立的连接还在存活期内SLB 不会强制切断存量连接。解决方法是权重调 0 后等存量连接自然超时或者直接在 ECS 上停止服务端口监听让后续连接立即失败。这条对发布流程很重要想要“无损摘除”要提前一段时间调权重不要等发布那一刻才动手。6. 装完怎么验证从端口探活到全链路压一遍迁移做完不是“能打开就算成功”我会按四层顺序验证一遍端口探活、组件连通、流量分发、故障切换。首先是各组件验证清单组件验证命令预期结果ECS 端口ss -lntp80、443、8081 等端口均已监听OSSossutil ls oss://bucket/对象列表正常返回RDSmysql -h your-rds.mysql.rds.aliyuncs.com -P 3306 -u app_user -p -e select 1返回数字 1SLBcurl -I http://your-domain.com/HTTP 状态码 200健康检查SLB 控制台后端服务器状态两台 ECS 均为“正常”组件验证通过后看流量分发。用循环请求打向 SLB 域名同时盯住两台 ECS 的后端访问日志# 循环请求 30 次观察响应码 for i in {1..30}; do curl -s -o /dev/null -w %{http_code}\n http://your-domain.com/index.html; done # 在每台 ECS 上分别观察后端日志 tail -n 20 /app/web-backend/logs/console.log两台 ECS 的日志里都有请求记录说明 SLB 在按权重分发流量。如果 30 次请求全部落在同一台机器上检查权重和会话保持配置确认不是健康检查误判导致一台被摘除。故障切换验证是最后一道也是最有价值的一道。手动停掉一台 ECS 上的业务服务模拟单机宕机# 在 ECS A 上执行 systemctl stop web-backend此时 SLB 会在下一轮健康检查后自动摘除这台机器循环请求仍然全部返回 200只是日志全部落在 ECS B 上。之后把 ECS A 的 web-backend 重新启动等健康检查恢复为“正常”流量自动回到两台机器。这一步验证的不只是 SLB 本身还验证了健康检查参数、后端服务启动脚本、systemd 自启配置全链路闭合。全链路验证不能只靠命令行我会在浏览器里开无痕模式走一遍真实业务路径访问首页、加载一张 OSS 上的图片、执行一次带数据库查询的搜索确认图片从 OSS 加载、数据从 RDS 返回、请求经过 SLB 分发。图片加载用浏览器 F12 看网络面板确认静态资源域名指向 OSS数据库查询则看 RDS 控制台的监控曲线是否有新 QPS。从那以后我每次做完迁移都强制自己走一遍“端口探活 → 组件连通 → 流量分发 → 故障切换”四步验证至少跑满两轮而不是看一眼页面能打开就宣布迁移完成。这套验证习惯帮我拦下过好几次“看似成功、实际单点”的隐患希望帮到你。本文还有配套的精品资源点击获取