ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

若依微服务从单节点k8s迁移到阿里云ECS:准不停服迁移与JMeter压测实战

若依微服务从单节点k8s迁移到阿里云ECS:准不停服迁移与JMeter压测实战 1. 从单节点 k8s 到阿里云 ECS若依微服务迁移的完整拆解把一套跑在单节点 k8s 上的若依微服务整套环境准不停服、不丢数据地搬到阿里云 ECS 上这件事听起来像是一次普通的“搬家”但真正动过手的人都知道它更像是在高速行驶中给汽车换轮胎。若依微服务本身包含网关、认证、系统模块、业务模块、定时任务、文件服务等多个组件每个组件都有自己的状态和依赖关系单节点 k8s 环境下这些组件共享同一个节点的网络、存储和资源池迁移时任何一个环节的疏漏都可能导致数据不一致或服务中断。我之所以关注这个场景是因为它和“QQ 全量上云”这类大规模迁移在方法论上有相通之处核心都不是“把程序复制过去”这么简单而是要在保证业务连续性的前提下完成计算、存储、网络、配置、数据五个层面的同步切换。下面我会从迁移前的环境盘点、数据同步策略、流量切换方案、压测验证四个维度把整套流程拆开来讲每一步都说明为什么这么做以及实际执行时容易踩的坑。1.1 迁移前必须盘清楚的五类资产很多人拿到迁移任务后第一反应是“先搭新环境”结果搭到一半发现旧环境里还有没记录的定时任务、没导出的 Nacos 配置、没同步的 MinIO 文件回头再补就很容易漏。我的习惯是先做一次完整的资产盘点把下面五类东西列成表格逐项确认迁移方式。资产类型具体内容迁移方式风险点计算资源各微服务 Pod、JVM 参数、副本数重新部署到 ECS 上的 k8s 或直接 Docker Compose资源配额不一致导致 OOM配置数据Nacos 配置、环境变量、密钥导出 JSON 后导入新 Nacos命名空间和分组容易搞混持久化数据MySQL、Redis、MinIO主从同步或停机窗口内导出导入字符集、时区、自增 ID 冲突网络入口Ingress、SLB、域名解析新环境先配好切换时改 DNS 权重TTL 过长导致切换延迟定时任务XXL-Job、Quartz 任务新环境先暂停切换后统一启用双跑导致重复执行这张表看起来简单但每一项背后都有细节。比如 Nacos 配置导出时很多人只导了DEFAULT_GROUP忘了自定义分组下的配置MySQL 迁移时只关注了数据量大的业务表忽略了QRTZ_开头的 Quartz 表结果新环境定时任务全部失效。我的建议是盘点阶段就让开发、运维、DBA 三方一起过一遍每个人负责自己熟悉的领域最后交叉检查。1.2 为什么选择“准不停服”而不是“完全不停服”“准不停服”这个词很微妙它意味着可以接受极短时间的只读或降级但不能接受长时间全站不可用。对于若依这类内部管理系统或中等规模业务系统完全不停服迁移的成本极高需要做双写、双向同步、灰度切流工程量可能比迁移本身还大。而“准不停服”允许我们在切换窗口内把服务设为只读通常控制在 5 到 15 分钟用户感知就是“系统卡了一下”而不是“系统挂了”。具体做法是在旧环境和新环境都部署好之后先通过 MySQL 主从复制让新库实时同步旧库数据Redis 用replicaof做从节点同步MinIO 用mc mirror做增量同步。切换时按以下顺序操作旧环境入口层返回 503 或维护页面停止写入确认主从同步延迟为 0新库提升为主库新环境 Nacos 配置切换为指向新库和新 Redis新环境各微服务重启或刷新配置DNS 或 SLB 权重切到新环境验证核心接口后恢复写入。这个顺序的关键在于“先停写、再确认同步、最后切流量”而不是反过来。我见过有人先切流量再同步数据结果新环境读到的还是旧数据用户以为数据丢了其实是同步没完成。1.3 单节点 k8s 迁移到 ECS 的两种落地形态单节点 k8s 本身资源有限迁移到阿里云 ECS 后你可以选择继续用 k8s比如在 ECS 上装 k3s 或 kubeadm 单节点也可以直接退化成 Docker Compose 部署。两种方式各有适用场景。继续用 k8s 的好处是保留了原有的 Deployment、Service、ConfigMap 等编排能力迁移时只需要把镜像和 YAML 搬过去改动最小。但单节点 k8s 在 ECS 上跑要注意 ECS 的安全组、弹性网卡、云盘挂载和本地 k8s 的 StorageClass 差异。比如原来用 local-path 做存储迁移后如果没挂载对应的云盘路径Pod 会一直 Pending。退化成 Docker Compose 的好处是运维简单不需要维护 k8s 组件资源开销也小。但缺点是失去了滚动更新、健康检查、自动重启等能力需要自己写脚本或 systemd 来保障。我的经验是如果原环境只是“用 k8s 跑容器”而没有用到复杂的编排特性迁移到 ECS 时直接上 Docker Compose 反而更稳出问题时排查链路短不用在 k8s 的网络和存储抽象里绕圈子。1.4 数据同步的三种武器MySQL、Redis、MinIO数据同步是迁移中最不能取巧的部分。MySQL 用主从复制做全量加增量配置时注意binlog_format必须是 ROW否则某些函数或触发器会导致主从不一致。Redis 用replicaof做从节点切换时在新环境执行SLAVEOF NO ONE提升为主节点。MinIO 用mc mirror --watch做持续同步切换前再跑一次全量校验。这里有个容易忽略的点MySQL 主从同步时如果旧库有lower_case_table_names1而新库是 0表名大小写敏感会导致查询报错。Redis 如果开了appendonly yes从节点同步的是 AOF 流切换后要确认 AOF 文件完整。MinIO 的mc mirror默认不删除目标端多余文件如果旧环境删过文件新环境会残留需要用--remove参数。提示数据同步完成后一定要用pt-table-checksum或自己写脚本对核心表做行数和关键字段校验不要只看同步延迟为 0 就认为数据一致。2. 压测验证用 JMeter 摸清云上环境的真实承载能力迁移完成后环境能不能扛住真实流量不能靠感觉必须用压测数据说话。压测人员peseman使用配套的 JMeter 脚本做高并发测试这个环节的目标不是“跑出一个好看的数字”而是找到云上环境的瓶颈点验证它是否满足业务预期。2.1 压测脚本设计从单接口到全链路JMeter 脚本的设计直接决定压测结果有没有参考价值。我见过很多人只压一个登录接口看到 TPS 很高就认为系统没问题结果真实业务一上来就崩。正确的做法是分层设计单接口基准测试每个核心接口单独压摸清单个接口的响应时间和吞吐量上限混合场景测试按真实业务比例混合多个接口比如 70% 查询、20% 写入、10% 登录全链路测试从网关入口开始经过认证、业务处理、数据库读写、缓存访问完整走一遍。JMeter 脚本里要用到 CSV Data Set Config 做参数化避免所有请求用同一个用户导致缓存命中率虚高。还要加 Response Assertion 校验返回内容不能只看 HTTP 状态码是 200 就认为成功有些系统出错时也返回 200但 body 里是错误信息。2.2 压测环境与生产环境的差异控制压测最怕的是“压测环境跑得很好生产环境一上线就崩”。差异通常来自几个方面ECS 规格不同、数据库连接池配置不同、Redis 最大连接数不同、SLB 带宽不同。我的做法是压测环境尽量和生产环境保持同规格如果成本不允许至少要把 CPU、内存、带宽三个关键指标对齐。另外压测时要注意阿里云 ECS 的带宽限制。如果压测机和新环境不在同一个 VPC 内走公网压测带宽瓶颈会先于应用瓶颈出现。建议压测机和新环境放在同一个 VPC用内网 IP 压测排除网络带宽的干扰。2.3 压测结果解读TPS、RT、错误率三者缺一不可拿到压测报告后不要只盯着 TPS。TPS 高但 RT 很长说明系统在“硬扛”用户体验很差TPS 高、RT 短但错误率高说明系统在“丢请求”实际可用性很低。三个指标要一起看指标健康范围异常表现可能原因TPS达到业务峰值 1.5 倍远低于预期连接池太小、GC 频繁、锁竞争RTP99 小于 500msP99 超过 2s慢 SQL、缓存穿透、线程阻塞错误率小于 0.1%超过 1%超时、连接拒绝、OOM如果压测中发现 TPS 上不去先用top、iostat、arthas看 CPU、磁盘、JVM 状态。若依微服务里最容易出问题的是网关和认证模块网关的线程池配置、认证模块的 Redis 连接数都是常见瓶颈。2.4 压测后的调优从 JVM 到数据库连接池压测不是为了证明系统不行而是为了找到调优方向。常见的调优点包括JVM 参数堆内存设置要合理不要超过 ECS 物理内存的 70%否则容易触发 swapGC 日志要打开方便分析 Full GC 频率数据库连接池HikariCP 的maximumPoolSize不是越大越好一般按CPU 核数 * 2 磁盘数估算过大反而导致数据库连接争抢Redis 连接池maxTotal和maxIdle要匹配业务并发量testOnBorrow建议关闭用testWhileIdle代替减少每次获取连接的开销Nginx 或 SLB 超时后端 RT 较长时要同步调整代理层的proxy_read_timeout否则会出现后端还在处理、前端已经超时的情况。调优之后要重新压测对比调优前后的数据确认改动有效。不要一次改多个参数否则出了问题不知道是哪个参数导致的。3. 迁移过程中最容易翻车的五个细节迁移这件事大方向谁都能说清楚真正决定成败的是细节。下面这五个坑每一个我都见过真实案例有的甚至导致迁移回滚。3.1 Nacos 命名空间和分组错位若依微服务用 Nacos 做配置中心和注册中心迁移时如果新环境的 Nacos 命名空间 ID 和旧环境不一致服务启动后会找不到配置或者注册到错误的命名空间导致服务间调用失败。更隐蔽的是分组group问题有些配置在DEFAULT_GROUP有些在自定义分组导入时如果没指定分组全部落到默认分组服务读取时就会报“配置不存在”。我的做法是导出配置时按命名空间和分组分别导出导入时严格对应。导入完成后用 Nacos 的“配置对比”功能逐项核对确认 key 和 value 都一致。服务启动后先看注册列表是否完整再看配置是否加载成功最后才做接口验证。3.2 MySQL 时区和字符集不一致旧环境 MySQL 可能是UTC时区新环境默认是CST迁移后时间字段全部偏移 8 小时。字符集方面旧库是utf8mb4新库如果建库时用了utf8emoji 和特殊字符会插入失败。这两个问题在迁移初期不会暴露等到业务写入时才报错排查起来很费时间。解决办法是在新库初始化时就明确指定character_set_serverutf8mb4、collation_serverutf8mb4_general_ci、default-time-zone08:00并且和旧库保持一致。如果旧库是 UTC新库也先设 UTC迁移完成后再统一调整不要一边迁移一边改时区。3.3 Redis 持久化配置导致数据丢失Redis 如果只做缓存丢了可以重建但如果存了 session 或分布式锁丢了就是事故。迁移时如果新 Redis 没开 AOF或者appendfsync设成everysec但在切换瞬间宕机就可能丢最后 1 秒的数据。对于关键业务建议切换前手动执行BGSAVE确认 RDB 文件生成后再切换。另外Redis 从节点提升为主节点后要检查maxmemory-policy是否和旧环境一致。旧环境如果是allkeys-lru新环境如果是noeviction内存满了之后写入会直接报错。3.4 文件存储路径和权限问题若依的文件上传功能通常存到本地磁盘或 MinIO。如果存本地磁盘迁移后新 ECS 的挂载路径、目录权限、磁盘空间都要确认。我遇到过新环境磁盘挂载到了/data但应用配置里写的是/home/ruoyi/uploadPath结果上传文件全部失败。如果存 MinIO要确认 bucket 名称、access key、secret key、endpoint 都正确并且新环境的 MinIO 已经同步了旧文件。3.5 定时任务双跑导致数据重复迁移切换时如果旧环境的定时任务没停新环境的定时任务又启动了同一个任务会执行两次。对于“统计当日订单”这类任务重复执行可能只是浪费资源但对于“给用户发短信”这类任务重复执行就是生产事故。正确做法是切换前先暂停旧环境所有定时任务确认没有正在执行的任务后再在新环境启用。XXL-Job 可以在执行器管理里把旧执行器下线Quartz 可以把QRTZ_TRIGGERS表里的TRIGGER_STATE改为PAUSED。切换完成后再逐个恢复。4. 从 QQ 全量上云看大规模迁移的通用方法论虽然我们讨论的是若依微服务迁移到阿里云 ECS但“QQ 全量上云”这类超大规模迁移背后的方法论是相通的。把视角拉高可以看到几个通用的原则。4.1 迁移不是复制而是重新设计很多人把迁移当成“把旧环境的东西原样搬到新环境”但旧环境往往积累了大量历史包袱过期的配置、无用的依赖、硬编码的 IP、写死的路径。迁移正好是一次清理的机会。我在迁移若依环境时顺手把 Nacos 里半年没用的配置删了把 Docker 镜像从latest改成固定版本号把配置文件里的硬编码 IP 换成环境变量。这些改动在迁移时做成本最低迁移后再做就要重新走一遍测试流程。4.2 可观测性要先于迁移建设迁移过程中最怕的是“出问题了不知道哪里出问题”。所以在迁移前新环境的日志、监控、告警要先建好。若依微服务可以接入 Prometheus Grafana 做 JVM 和接口监控接入 Loki 或 ELK 做日志收集接入 Alertmanager 做告警。压测时这些监控数据就是调优依据切换时这些监控就是安全网。4.3 回滚方案不是可有可无的备选项任何迁移方案都必须包含回滚方案而且回滚方案要经过验证。回滚不是“把 DNS 切回去”这么简单因为切换期间新环境可能已经写入了数据切回旧环境后这些数据就丢了。所以回滚方案要明确什么条件下回滚、回滚时新环境的数据怎么处理、回滚后旧环境能否立即提供服务。我的经验是切换窗口内先让新环境只读运行一段时间确认没问题后再开放写入这样回滚时数据冲突最小。4.4 压测是迁移的验收标准不是可选项没有压测的迁移就像没有试飞的航班。压测不仅验证新环境的承载能力还能暴露配置错误、网络延迟、依赖缺失等问题。JMeter 脚本要覆盖核心业务场景压测结果要形成报告明确新环境的容量上限和瓶颈点。如果压测不通过宁可推迟切换也不要带着问题上线。5. 写在最后一些个人体会迁移这件事技术方案只占三成剩下七成是沟通和协调。开发要知道哪些接口不能停DBA 要确认同步延迟运维要准备好回滚脚本压测人员要提前写好 JMeter 脚本。任何一方掉链子迁移都会卡住。我自己的习惯是迁移前开一次全员对齐会把时间窗口、操作步骤、负责人、回滚条件全部列清楚每个人确认自己的部分。迁移当天用共享文档实时记录每一步的操作时间和结果出问题时能快速定位是哪一步引入的。迁移完成后不要急着庆祝先观察 24 小时确认没有异常再收尾。最后分享一个小技巧如果条件允许先在测试环境完整走一遍迁移流程包括数据同步、流量切换、压测验证。测试环境踩过的坑生产环境就能避开。测试环境没踩到的坑生产环境大概率也会遇到但至少你已经有了一套可复用的操作手册。
返回列表