思路:环境迁移的核心是服务运行实例+流量切换
对于k8s来说,就是先执行Deployment部署实例,然后配置Ingress暴露服务,验证没问题后再把原有域名解析切换到新的服务
过程:
在集群内部署注册中心,各项目组部署应用,并注册服务到集群内的新注册中心
部署完成后,验证服务是否正常(存在依赖关系的应用需全部部署)
验证完成后,修改域名指向,进行外部流量切换
流量切分完毕后,原 dev/UAT 环境停机,并回收资源
分布式环境服务之间都有着各种的调用关系,所以环境迁移要保证新环境有依赖的服务实例可调用,所以可以分成两步:
1:先部署所有服务实例到新环境
先部署实例会遇到的困难:
1.1 :普通的服务间调用都是由外部发起,即服务通过内外网域名等方式暴露地址出去之后才会有流量,由于这里我们先只部署,还没暴露服务,所以不用担心这次部署会因为外部流量造成问题
1.2: 部署的服务可能有消费 mq 消息,定时任务等自发起的流量,这时我们要保证新部署到新环境的实例能屏蔽这部分流量,防止跟外面已经在跑的环境冲突消费,
1.2.1:这里以 xxl-job 为例。假如服务用了 xxl-job,部署到新环境有必要不运行定时任务,可以通过修改配置实现
-Dxxl.job.admin.addresses=
这样就可以保证,部署到新环境的服务不会运行 xxl-job 的定时任务,其他定时任务也可以通过类似的方式修改达到目的
1.2.2:这里以 RabbitMQ 为例。假如服务用了 xxl-job,部署到新环境有必要不消费队列里的消息,可以通过修改配置实现
-Dspring.rabbitmq.virtual-host=404
即配置一个不存在的 vhost,这样服务启动后就不会消费消息,而且不影响服务启动成功
或者其他方式,例如注释 RabbitListener 代码,缺点是需要改代码
注意:以上配置一般通过 - D 覆盖,这样可以不用改 Apollo 上的配置,因为 Apollo 的配置外面正常跑的实例还在用,不要互相影响。
1.3 注册中心
如果服务用到注册中心,如 Eureka,需要先修改Eureka的注册中心地址
1.4 恢复配置
等所有服务都在新环境部署新实例后,则可以恢复原来的配置让实例正常的消息 mq 和定时任务
2: 新增路由
第一步都完成之后,所有的服务实例都部署到新的环境里了,服务注册中心上也有相应的实例,这时候我们可以开始验证了
对于旧服务,一般都有自己正在使用的域名,这时我们可以对原有域名在新环境新增一个应用路由,用于暴露部署的服务实例
部署完后可以通过本地绑 hosts 的方式进行访问,域名绑定页面上的这个入口 ip 地址即可
对于 https 的场景,使用命令验证 https 是否生效:
curl --resolve domain:443:ip /check_status
验证没问题后让运维切域名流量到指定的 ip
优势:
以上迁移分为 2 个步骤,业务方可以只关注第二步即验证确保迁移没问题,第一步可以交由专人来部署,职业分明,降低业务方接入的成本
回顾:
以上过程,新旧 2 套环境都是完全隔离,互不影响,只有等新环境的验证没问题了才切换流量到新环境,最大程度地避免了迁移环境期间的故障。不仅可用于迁移效能平台,迁移其他环境大体思路也可参考,包括生产切换环境也可以考虑使用
总结:
此方案并不要求新旧两套环境之间的服务网络打通,但是对于数据库 mysql,redis,消息队列 mq 这些中间件,是需要在新环境打通原有的网络,因为这些都涉及持久层,迁移起来可能比较困难。如果要迁移数据库可以等流量切到新环境后,在新环境部署新的数据库,然后旧数据库单向同步数据到新数据库,然后再流量低峰期修改连接的数据库到新环境的数据库
而对于注册中心 Eureka 和 xxl-job,这些组件要求先部署到新环境