ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

若依微服务准不停服迁移上云:VPC、CLB与Kubernetes实战

若依微服务准不停服迁移上云:VPC、CLB与Kubernetes实战 1. 从一次真实的迁移需求说起去年底我接手了一个挺有意思的活儿把一套跑在单节点 Kubernetes 上的若依微服务整套环境准不停服、不丢数据地迁移到云上 ECS。这个需求和 QQ 全量上云在本质上是同一类问题——都是把原本跑在物理机或自建机房里的核心业务平滑搬到云上同时保证业务不中断、数据不丢失。区别只是规模大小QQ 是亿级用户的全量上云我们这套若依环境是几十个微服务的中小规模迁移但底层要解决的技术问题是一样的。如果你正在做类似的事情——不管是把自建机房的业务往云上搬还是把一套微服务从一台机器挪到另一台机器又或者你只是好奇“全量上云”这四个字背后到底藏着多少技术细节——那这篇内容应该能给你一些直接能用的参考。我会从整体设计思路、核心组件选型、实操迁移步骤、压测验证方法、常见问题排查这几个维度把整个迁移过程拆开来讲清楚。涉及到的关键词包括 VPC、CLB、Kubernetes、ECS、JMeter 压测等这些我都会结合实际操作来说明它们在整个链路里扮演什么角色。先说清楚一个前提全量上云不是把镜像打包往云上一扔就完事了。它涉及到网络架构的重新设计、流量入口的切换、数据的一致性保障、回滚方案的准备以及迁移后的承载能力验证。任何一个环节出问题都可能导致业务中断或者数据丢失。所以下面我会按照实际操作的顺序一层一层往下拆。2. 整体迁移方案的设计思路与选型考量2.1 为什么选择“准不停服”而不是“完全不停服”先解释一下“准不停服”这个概念。完全不停服意味着在整个迁移过程中用户请求一秒都不能断这对架构的要求极高通常需要双活或者灰度切流的方案成本很高。而“准不停服”允许在切换的瞬间有极短的服务不可用窗口比如几秒到几十秒但数据绝对不能丢业务恢复后用户无感知。对于若依微服务这套环境来说选择准不停服是性价比最高的方案。原因有三点第一若依的微服务架构本身支持多实例部署可以通过滚动更新的方式减少中断时间第二单节点 K8s 意味着没有高可用集群无法做到真正的零中断第三迁移窗口可以安排在业务低峰期几十秒的中断对业务影响可控。注意如果你面对的是金融交易类或者医疗类业务准不停服可能不够需要设计双写或者双活的方案。但对于大多数企业内部管理系统、电商后台、SaaS 应用来说准不停服完全够用。2.2 网络架构VPC 是整个迁移的地基上云第一步不是搬应用而是规划网络。VPCVirtual Private Cloud虚拟私有云是云上网络的基石它决定了你的 ECS、数据库、负载均衡等资源怎么互联互通。在自建机房里你可能习惯了用物理交换机划分 VLAN 来隔离网络。VPC 和 VLAN 的核心差异在于VLAN 是二层隔离VPC 是三层隔离且天然支持跨可用区。VPC 内部可以再划分子网Subnet每个子网绑定一个可用区这样你的应用可以跨可用区部署获得更高的可用性。我的规划是这样的创建一个 VPC网段选 10.0.0.0/16然后在里面划分三个子网——一个公网子网放 CLB 和跳板机一个私网子网放 ECS 应用节点另一个私网子网放数据库和 Redis。公网子网的路由表指向互联网网关私网子网的路由表指向 NAT 网关用于出站访问。这样应用节点不直接暴露在公网安全性更高。2.3 流量入口CLB 承担了什么角色CLBConfigurable Load Balancer可配置负载均衡是云上的流量入口。在自建机房里你可能用 Nginx 或者 LVS 来做负载均衡上云之后 CLB 接管了这个职责。为什么不用自己搭 Nginx 做负载均衡因为 CLB 是云平台托管的服务它自带高可用、自动扩缩容、健康检查、SSL 卸载等功能。你不需要担心 Nginx 单点故障也不需要自己维护 Keepalived 做 VIP 漂移。CLB 后面可以挂多台 ECS流量按你配置的权重或者轮询策略分发。在迁移过程中CLB 还有一个关键作用它可以让流量切换变得非常平滑。你先把新的 ECS 节点挂到 CLB 后端等健康检查通过后再逐步把流量从旧节点切到新节点。整个过程对用户来说几乎无感知。2.4 容器编排单节点 K8s 的局限与应对单节点 K8s 意味着整个集群只有一个 Master 节点同时也承担 Worker 的角色。这种架构的优点是部署简单、资源占用少缺点是没有任何高可用能力——节点一挂整个集群就不可用。迁移到云上 ECS 之后我建议至少把 Master 和 Worker 分开或者直接使用云平台托管的 K8s 服务。如果预算有限至少要做到Master 节点配置稍高一些4C8G 起步Worker 节点根据业务负载来定etcd 数据定期备份到对象存储关键微服务至少两个副本利用 K8s 的调度能力分散到不同节点。实操心得单节点 K8s 迁移时最大的坑是 PVPersistent Volume的迁移。如果你的微服务用了本地存储或者 NFS迁移时需要先把数据同步到云上的 NAS 或者云盘再重新挂载。千万不要直接复制 Pod 的 YAML 就完事存储卷的配置一定要仔细核对。3. 核心组件拆解与迁移前的准备工作3.1 若依微服务的架构梳理若依RuoYi是一套基于 Spring Cloud 的微服务快速开发框架通常包含以下核心组件网关Gateway、认证中心Auth、系统模块System、业务模块Business、定时任务Job、代码生成Gen等。每个模块都是一个独立的 Spring Boot 应用注册到 Nacos 或者 Eureka 做服务发现配置统一放在配置中心。迁移之前我做的第一件事是把所有微服务的依赖关系画出来。哪些服务调用了哪些服务哪些服务依赖了数据库、Redis、MQ哪些服务有定时任务哪些服务是无状态的。这张图直接决定了迁移的顺序和方式。无状态服务比如网关、认证中心迁移最简单直接在新环境部署改一下注册中心地址就行。有状态服务比如依赖本地文件、本地缓存的需要额外处理数据迁移。定时任务服务需要特别注意迁移过程中要避免新旧两个环境同时执行定时任务否则会出现重复执行的问题。3.2 数据库迁移不丢数据的核心保障数据不丢是迁移的底线。若依默认使用 MySQL迁移方案我推荐用主从复制的方式先在云上 ECS 部署一个新的 MySQL 实例配置为旧库的从库等数据同步追平后再执行主从切换。具体步骤是这样的第一步在旧库上开启 binlog创建复制账号第二步在云上 MySQL 上执行 CHANGE MASTER TO 指向旧库启动复制第三步观察 Seconds_Behind_Master 指标等它降到 0 并且稳定一段时间第四步在业务低峰期锁住旧库的写入FLUSH TABLES WITH READ LOCK确认从库数据完全同步后把应用的数据库连接地址切到新库第五步解除旧库的锁完成切换。注意切换过程中一定要先停掉所有写入操作否则会出现数据不一致。如果你用的是云平台的数据库迁移服务DTS它可以帮你自动完成增量同步和切换省去手动操作的麻烦但核心原理是一样的。3.3 Redis 和消息队列的迁移策略Redis 的迁移相对简单如果数据可以容忍短暂丢失直接在新环境启动一个空的 Redis让应用重新预热缓存就行。如果数据不能丢可以用 Redis 的主从复制或者 RDB/AOF 文件迁移。消息队列比如 RabbitMQ 或者 RocketMQ的迁移要复杂一些。核心问题是迁移过程中生产者和消费者的连接会断开消息可能丢失或者重复消费。我的做法是先在新环境部署好 MQ然后逐步把消费者切换到新 MQ等消费者都切完之后再切换生产者。切换期间旧 MQ 里的积压消息需要手动处理或者等待消费完毕。3.4 镜像与配置的准备工作所有微服务的 Docker 镜像需要提前构建好并推送到云上的镜像仓库。如果你用的是腾讯云那就是 TCRTencent Container Registry如果用阿里云就是 ACR。镜像的 tag 一定要规范建议用 Git commit ID 或者版本号不要用 latest否则回滚的时候你会很痛苦。配置文件方面K8s 的 ConfigMap 和 Secret 需要根据云上环境重新调整。比如数据库地址、Redis 地址、Nacos 地址这些都要改成云上的内网地址。建议把配置项做成环境变量或者配置中心管理不要硬编码在镜像里。4. 实操迁移过程与关键环节实现4.1 云上 K8s 环境的搭建如果你选择自建 K8s可以用 kubeadm 在 ECS 上初始化集群。操作系统建议用 Ubuntu 20.04 或者 CentOS 7.9Docker 版本用 20.10.xK8s 版本用 1.24.x注意 1.24 之后不再默认支持 Docker 作为容器运行时需要额外安装 cri-dockerd。初始化 Master 节点的命令大致如下kubeadm init \ --apiserver-advertise-address10.0.1.10 \ --pod-network-cidr10.244.0.0/16 \ --service-cidr10.96.0.0/12 \ --kubernetes-versionv1.24.0初始化完成后按照提示配置 kubectl 的 kubeconfig然后安装网络插件Calico 或者 Flannel。接着把 Worker 节点 join 进来。如果你用的是云平台托管的 K8s这一步可以跳过直接在控制台创建集群即可。4.2 微服务的部署与注册中心切换所有微服务通过 Helm Chart 或者 kubectl apply 部署到 K8s 集群。部署顺序很重要先部署 Nacos 或者 Eureka 作为注册中心再部署网关和认证中心最后部署业务模块。每个微服务的 Deployment 里要配置好 readinessProbe 和 livenessProbe这样 K8s 才能正确判断 Pod 是否就绪。readinessProbe 建议用 HTTP GET 请求健康检查接口比如 /actuator/health初始延迟设 30 秒间隔 10 秒。服务注册中心的切换是迁移的关键节点。旧环境的微服务注册在旧 Nacos 上新环境的微服务注册在新 Nacos 上。在切换瞬间需要把网关的路由配置指向新 Nacos 的服务列表。这个过程可以通过修改网关的配置中心来实现不需要重启网关。4.3 CLB 流量切换的具体操作CLB 的流量切换是整个迁移过程中最需要谨慎操作的环节。我的做法是分三步走第一步在新环境的 ECS 上部署好所有微服务确保服务能正常启动并注册到 Nacos。此时 CLB 后端还没有挂任何新节点用户流量仍然走旧环境。第二步把新环境的网关节点挂到 CLB 后端权重设置为 1旧节点权重 100。观察一段时间确认新环境能正常处理请求没有报错。第三步逐步调高新节点的权重同时降低旧节点的权重。比如新节点权重调到 10旧节点降到 90观察 5 分钟没问题再调到 50/50最后调到 100/0完成流量切换。实操心得CLB 的健康检查一定要配置正确。如果健康检查路径返回 200 才算健康那你的网关必须提供一个返回 200 的健康检查接口。健康检查间隔建议设 5 秒不健康阈值设 3 次健康阈值设 2 次。这样即使新节点有问题CLB 也能快速把它摘掉不影响用户。4.4 数据一致性校验与回滚方案流量切换完成后不要急着把旧环境关掉。至少观察 24 小时确认新环境运行稳定、数据写入正常、没有异常日志。数据一致性校验的方法对比新旧数据库的关键表记录数、最近更新时间、关键字段的汇总值。如果发现不一致需要立即排查原因。常见的原因包括切换瞬间有未同步的 binlog、应用连接池还连着旧库、定时任务在新旧环境同时执行等。回滚方案必须提前准备好。如果新环境出现严重问题需要能快速把流量切回旧环境。回滚的前提是旧环境还在运行数据库还没有被新环境写入大量数据。所以切换后的观察期内旧环境要保持待命状态数据库要保留只读或者可写但能快速回滚的能力。5. 压测验证用 JMeter 验证云上环境的承载能力5.1 压测脚本的设计与参数化迁移完成后由压测人员使用 JMeter 脚本做高并发测试验证云上环境的承载能力。压测脚本的设计要贴近真实业务场景不能只压一个接口。我的做法是先用抓包工具或者日志分析统计出业务高峰期的主要接口调用比例。比如登录接口占 10%查询接口占 60%写入接口占 20%其他接口占 10%。然后按照这个比例设计 JMeter 的线程组和请求分布。参数化方面用户账号、密码、查询条件这些都要从 CSV 文件读取避免所有请求用同一个参数导致缓存命中率过高压测结果失真。JMeter 的 CSV Data Set Config 组件可以很方便地实现这一点。5.2 压测执行与监控指标压测执行时需要同时监控以下指标监控维度具体指标工具应用层QPS、响应时间、错误率JMeter Aggregate Report容器层CPU、内存、网络 IOkubectl top pods节点层CPU、内存、磁盘 IO云监控控制台数据库连接数、慢查询、QPSMySQL 慢日志、云数据库监控中间件Redis 命中率、MQ 积压量Redis INFO、MQ 控制台压测从低并发开始逐步增加线程数观察各项指标的变化。如果响应时间突然飙升或者错误率上升说明达到了瓶颈需要停下来分析原因。5.3 瓶颈分析与调优压测过程中常见的瓶颈和调优方法CPU 瓶颈微服务的 JVM 参数需要调整比如堆内存大小、GC 策略。建议用 G1 GC堆内存设为容器内存限制的 70% 左右。数据库瓶颈慢查询需要优化 SQL 和索引连接数不够需要调整最大连接数和连接池配置。网络瓶颈CLB 的带宽和连接数需要根据压测结果调整规格。Redis 瓶颈如果 QPS 过高可以考虑读写分离或者集群模式。注意压测环境的数据量和生产环境要尽量一致否则压测结果没有参考价值。如果生产环境有 100 万条数据压测环境只有 1 万条那数据库的查询性能会差很多。6. 常见问题与排查技巧实录6.1 迁移后服务注册不上 Nacos这是最常见的问题之一。排查思路先看 Pod 的日志确认 Nacos 地址配置是否正确再检查网络连通性在 Pod 里 ping 或者 telnet Nacos 的地址和端口最后检查 Nacos 的命名空间和分组配置是否一致。如果 Pod 能访问 Nacos 但注册不上可能是 Nacos 的鉴权配置问题。若依默认可能没开鉴权但云上的 Nacos 可能开了需要在微服务配置里加上用户名和密码。6.2 CLB 健康检查失败健康检查失败的原因通常有几种健康检查路径配置错误、后端服务没有正常启动、安全组没有放行健康检查的源 IP 段。云平台的 CLB 健康检查源 IP 段是固定的需要在 ECS 的安全组里放行。另外如果后端服务返回的是 302 跳转而不是 200健康检查也会失败。需要确认健康检查接口不经过认证拦截器。6.3 数据库主从切换后数据不一致主从切换后如果发现数据不一致首先检查 binlog 的格式。如果旧库用的是 STATEMENT 格式某些非确定性函数比如 NOW()、RAND()可能导致主从不一致。建议用 ROW 格式。其次检查是否有应用还在连旧库。切换后要确认所有应用的数据库连接地址都已经更新连接池已经刷新。可以通过在旧库上执行 SHOW PROCESSLIST 来查看还有哪些连接。6.4 压测时 QPS 上不去压测时 QPS 上不去但 CPU 和内存都没跑满这种情况通常是 JMeter 本身的瓶颈。JMeter 是 Java 应用单机并发能力有限。可以改用分布式压测用多台压测机同时施压。另外JMeter 的默认堆内存可能不够需要调整 jmeter.bat 或者 jmeter.sh 里的 HEAP 参数。还有JMeter 的监听器会消耗大量资源压测时建议只保留 Aggregate Report关掉 View Results Tree。6.5 迁移后定时任务重复执行这个问题很隐蔽但影响很大。如果新旧环境同时运行定时任务会执行两次可能导致数据重复写入或者业务逻辑错误。解决方法在迁移期间先把旧环境的定时任务停掉等新环境稳定后再在新环境启用。或者用分布式锁比如 Redis 锁来保证同一时间只有一个环境执行定时任务。6.6 常见问题速查表问题现象可能原因排查方法解决方案服务注册不上Nacos 地址错误、网络不通、鉴权失败看日志、telnet 测试修正配置、放行安全组健康检查失败路径错误、服务未启动、返回非 200手动 curl 健康检查接口修正路径、调整拦截器数据不一致binlog 格式、应用连旧库对比数据、SHOW PROCESSLIST改 ROW 格式、刷新连接池QPS 上不去JMeter 瓶颈、应用瓶颈看 JMeter 和应用的 CPU分布式压测、调优应用定时任务重复新旧环境同时运行检查两边日志停旧环境任务、加分布式锁7. 迁移后的收尾与个人体会迁移完成后旧环境的资源不要马上释放至少保留一周。这一周内新环境可能会暴露出一些在压测中没发现的问题比如某些边缘业务的接口超时、某些定时任务执行失败、某些报表查询变慢等。保留旧环境可以让你在紧急情况下快速回滚。监控和告警要配置到位。云监控可以配置 CPU、内存、磁盘、网络等基础指标的告警应用层可以配置接口响应时间和错误率的告警。告警阈值不要设得太敏感否则会被大量误报淹没也不要设得太宽松否则真出问题了收不到通知。我在实际操作中的体会是迁移这件事技术方案只占三成剩下七成是沟通和协调。你需要和业务方确认迁移窗口和压测人员确认测试计划和运维确认监控配置和开发确认代码兼容性。任何一个环节沟通不到位都可能在迁移当晚出问题。最后分享一个小技巧迁移前一定要做一次完整的演练。在测试环境把整个迁移流程走一遍记录每一步的耗时和遇到的问题。演练中暴露的问题越多正式迁移时就越顺利。我那次迁移演练发现了三个配置错误和一个脚本 bug正式迁移时一次成功切换窗口只用了 15 秒。
返回列表