贝聊VPC迁移

1,062 阅读9分钟

1. 背景

2013年贝聊正式成立,为了加快项目研发节奏,服务器使用了阿里云经典网络ECS服务器,4年后,随着贝聊业务高速发展,阿里云经典网络弊端逐渐展示出来。

经典网络服务器分配的IP地址不是连续的,没有固定的规则,运维人员需要人工维护繁琐的安全策略组,存在安全隐患;经典网络ECS默认分配1M的公网IP地址,费用会比VPC网络服务器贵,而这1M带宽是个鸡肋,满足不了生产环境业务间调用;经典网络给业务带来扩展性问题,跨机房部署在经典网络模式下变得复杂,服务的发现和注册均需适配解决,且不支持阿里云高速通道等高级功能。

阿里云专有网络,简称VPC网络,可以很好解决上述的问题,经过技术团队详细的评估后,我们决定尽快迁移服务为VPC网络。

2. 目标

1. 迁移的方案尽可能简单,业务需要改动工作量少

2. 迁移过程服务停机时间尽可能短。

3. 迁移后存储数据必须保证一致性。

4. 迁移方案必须支持迅速回滚。

3. 技术方案

3.1. 现况

贝聊业务框架大致划分4层,分别为接入层、Web层、Service层、存储层,如下图:


接入层使用阿里云SLB处理负载均衡,贝聊自建Nginx分发服务;Service层使用开源社区Dubbo框架治理服务;存储层使用阿里云RDS数据库和自建Redis分布式缓存。

3.2. 迁移方案

3.2.1. 域名梳理

贝聊使用DNSPod管理域名,历史因素影响,服务器存在很多未知用途的域名,迁移会可能会造成部分功能不可用。

这种历史问题确实没有非常好的解决方案,只能让运维导出所有的域名列表,各部门小组认领,认领后负责人需要登记业务和相关人员信息。运维对未认领的域名采取Nginx日志监控告警,避免梳理错误业务访问出错。

3.2.2. 第三方服务

贝聊部分功能依赖第三方供应商服务(如短信发送服务、支付宝),服务迁移需要考虑新环境对第三方服务兼容性,要对所有依赖第三方服务进行梳理,并测试第三方服务在新VPC环境是否正确工作。

有点大家要注意,VPC网络下ECS服务器获取公网IP地址不太一样,不能通过ifconfig获取了,如下


Dubbo服务注册在Zookeeper只会暴露内网ip地址,获取当前服务器公网IP地址可以curl ipinfo.io网络请求方式获取。

3.2.3. IP地址变更

迁移后所有服务重新部署,IP地址均发生变更,而目前大部分工程代码配置是硬IP地址,如下:

硬IP配置的方式会给我们项目迁移带来很大的风险,如果配置漏修改,会导致迁移后服务不可用。

针对上述问题,本次迁移把所有的硬IP地址替换为域名,让运维管理工作变得更方便,如果后续服务器出现硬件故障,不需要修改代码配置,运维进行域名变更即可。


3.2.4. 数据迁移

贝聊存储层保存了用户的资料交易等核心数据,不允许出现错误,存储层由阿里云RDS数据库和Redis分布式缓存集群组成,阿里云RDS支持“一键切换VPC网络”,非常完美帮助本次的VPC迁移工作。

Redis是我们自己搭建的集群,涉及很多业务,数据量非常庞大,部分缓存数据丢失可能会影响用户正常使用,迁移难度较大。

我们在GitHub发现了唯品会开源了一个好用数据迁移工具redis-migrate-tool,地址:github.com/vipshop/red…

10G迁移数据在可以在几分钟内完成传输(网络带宽资源要充足),同时redis-migrate-tool支持增量同步数据。

3.2.5. 测试验证

服务部署、启动、测试验证都是非常耗时过程,我们无法保证迁移当天短时间完成所有服务部署验证操作,况且迁移新环境存在很多未知因素。

为了规避风险,我们采取使用“提前部署和测试”方案,即提前在VPC服务器部署所有的服务,并对该服务进行测试验证,由于服务只对贝聊内部请求白名单开放,不会影响线上用户的使用。

阿里云RDS支持同时公网和内网连接操作数据库,VPC新环境临时使用公网访问经典网络RDS,保证“提前部署和测试”测试过程数据是一致性的,等其他迁移工作完成后,RDS执行“一键切换VPC网络”,快速完成数据库转换。

上图的VPC服务部署后,只能通过接口调用测试验证,操作非常麻烦,需准备详细的接口测试用例,办公电脑Host挟持可以完美解决我们问题,如下

“Host代理”即在我们办公电脑安装Charles、Fiddler抓包工具代理,本地电脑配置/etc/hosts,利用hosts解析转发请求到测试SLB,完美解决APP环境的切换。

3.2.6. Host控制

“IP地址变更”统一采用域名方式解决,“域名化”是本次迁移工作非常重要的变更,涉及Zookeeper、Elastic-job、Redis、Memcached等基础服务,Host控制管理非常重要。阿里云RDS也是基于域名地址提供服务的,提供了两个不一样的公网地址和内网地址。

VPC提前部署服务测试,通过公网连接经典网络RDS,在迁移完成后,RDS“一键切换为VPC网络”。数据网络切换为VPC后,需要修改工程代码指向VPC内网地址,并重新发布部署,工作非常繁杂,容易出错。

基于上述问题考虑,在迁移过程中,我们在每台服务器/etc/hosts采取域名绑定控制。

假设数据库ibl_test地址信息如下

内网:rm-bp14jsmqx123456.mysql.rds.aliyuncs.com公网:rm-bp14jsmqx123456o.mysql.rds.aliyuncs.com

步骤一、工程代码统一配置了内网地址

jdbc.driver=com.mysql.jdbc.Driver
jdbc.host = rm-bp14jsmqx123456.mysql.rds.aliyuncs.com/ibl_test

步骤二、VPC服务器配置/etc/hosts指向经典网络RDS地址

#RDS地址指向公网IP 
10.118.xxx.xx rm-bp14jsmqx123456.mysql.rds.aliyuncs.com

步骤三、迁移完成后,执行 “一键切换VPC网络”,把/etc/hosts配置移除,重启服务。

#RDS地址指向公网IP (注释)
#10.118.xxx.xx rm-bp14jsmqx123456.mysql.rds.aliyuncs.com

贝聊在阿里云100多台服务器,域名的切换要支持同时批量操作,ansible工具可以很好解决我们的需求。

Host控制给我们迁移工作带来了便利,但是也存在缺陷,如Java进程默认会对DNS有缓存,运维修改了/ect/hosts,可能无法立刻生效,对此为所有的Java进程配置了JVM参数networkaddress.cache.ttl合理值。

3.2.7. 风险控制

VPC迁移涉及所有贝聊服务器,风险非常大,本次迁移工作大概风险点:

1. 人工操作错误

2. 依赖第三方服务故障

3. 漏覆盖迁移服务

为了规避人工操作错误,我们在wiki制定了迁移过程所有人都必须遵循的操作步骤,如下


wiki上的操作步骤必须命令行、脚本化,不允许迁移当天再去输入Linux命令,这样会浪费大量时间和出现人工操作失误风险。

wiki虽然制定了操作步骤,每个人对文字步骤理解存在偏差,为此我们在测试环境组织了模拟线上的演练工作,要求每个操作人员都要理解wiki执行步骤,在一定程度规避了人工操作的风险。

如果在新环境出现严重的故障,迁移方案必须支持快速回滚,我们准备了一份回滚详细操作步骤,步骤从反方向执行迁移,完成回滚,下图

4. 迁移实施

4.1. 准备工作

迁移准备工作是非常繁琐的事情,涉及贝聊内部多个部门,我们把VPC迁移作为一个项目进行推进,每周同步各个团队的工作进度,使用wiki记录各团队执行的内容项。

4.2. 迁移演练

演练过程,所有关键人员必须就位,由一个负责人指挥协调所有的迁移工作,尽可能模拟线上的迁移。测试环境演练结束后,我们发现了很多问题,整个过程沟通不顺畅,人工操作错误,系统多次出现异常问题一下子暴露出来,导致迁移演练耗时4个小时,超过了我们的预期。

针对演练碰到的问题,所有负责人聚在进行技术复盘,重新又一次review所有的操作步骤,把不合理的步骤再一次完善。

4.3. 线上迁移

为了减少对用户的影响,线上迁移我们选择了凌晨执行,并提前了发客服公告,准了相对应的应急方案。

迁移当天,所有后台技术人员准时在工位就绪,我们按照wiki准备步骤有条不紊地展开迁移工作,短短的25分钟过后,我们成功完成了VPC迁移,共涉及100多台服务器,300多个Dubbo接口,30多项功能业务,约20G容量Redis内存数据迁移。

迁移完成后,所有人员须测试验证完业务功能,检查所有的服务运行情况,确保监控正常工作,交接好第二天值班人员事项。

5. 总结

VPC迁移看起来困难很大,但是认真执行后,其实没有想象中困难,这次迁移工作,我们总结出几点经验:

1. 要做详细迁移技术方案设计,针对关键步骤做技术调研,测试。

2. 使用类似wiki的项目管理工具制定统一操作步骤,避免人工误操作。

3. 迁移演练和步骤review方式避免人工误操作。

4. 面对面沟通会议,避免理解偏差。