前言
对于一个当前产品需求频繁迭代更换的年代,应用中的某个模块被下线、服务根据使用量扩缩容、数据库扩充合并的操作肯定是必不可少,而最近由于对一些服务资源使用的不合理,也对这些资源进行了下线、缩容、合并等操作。正所谓由奢入俭难
,下线服务、数据库合并都是非常危险的操作,并不是直接操作kill进程、释放数据库那么简单,需要注意的地方很多,因此总结一下。
服务下线
如果被下线服务前提是流量少,则需要做相关的数据统计,统计后与相应产品伙伴确认,
- 需要在网关层面统计服务器accesslog是否达到产品、运营同事规定的下线标准;
- 从数据库中统计相应使用UV数量。
服务下线前依赖资源统计
- 确认部署的各个环境服务器是否有共用情况,比如一个实例上部署多个服务,如果有则下线时无需处理该实例,通过linux进程名筛选及暴露端口;
- 同样确认该服务使用的中间件:数据库实例中有无其他库(或通过连接情况判断)、Mq的Topic、Redis实例的链接情况等;
- 还需要查看是否有被其他服务依赖的接口。
相关数据的备份
- 资源统计后,需要对所有数据进行备份,数据库中全量数据备份保存;
- Git仓库代码记录;
- 配置文件内容记录;
- 如果有必要还需要对整个服务的生命周期进行记录,需求文档、技术文档等;
- 该服务如果有单独域名,也需要记录各个环境下不同域名,需要最后释放。
服务下线前的信息同步
- 被下线的服务影响到客户端版本、服务器之间依赖等,需要与产品、运营、测试、技术支持的伙伴同步相应消息。
数据库合并
mysql数据库合并迁移
除了服务器的缩容与下线,也会有数据库实例的合并,数据迁移的话使用阿里云比较成熟dts同步工具,将数据从一个实例导入另外一个实例。
- 迁移时会增加数据库的iops,同步迁移时选在业务低峰期。
- 迁移后需要服务端发版改变对应数据库配置链接,需要更多的注意是否有多台机器、不同环境同时连接目标实例,特别需要注意数据同步的问题。如下图所示:我们的灰度(内测)环境与生产链接同一个数据库,如果线上发版时不能保证读写数据来源的一致性,就会导致这段时间数据的不一致性。如下图所示,如两台ecs服务器在发版中连接不同的数据库实例,而其中源实例A使用dts同步向目标实例B写入数据时,如果出现双写(两台ecs服务同时写入数据)便会导致数据的不一致性。
方案:生产发版时 kill掉内测服务,在生产发版结束后再重启内测服务,并且在生产发版时采用摘机方式发版。
redis合并与迁移
对于redis我们大多用来当做缓存,有少量的未持久化的业务数据也使用redis实现,如使用zset来计算学生排名。我们也是使用云上工具dts进行迁移,迁移时需要注意以下问题:
- 相同key数据需要确实是否可以覆盖或者跳过;
- 相同key,相同的业务数据value,但是对应value的序列化方式不一致,需要重点考虑,如下图所示,相同的value及相同的业务数据value,在不同的服务中对value取值和赋值时采用的序列化方式不一致,会导致其他服务的数据异常问题;如下图,serviceA和serviceB在进行redis合并后,有相同的key,且key序列化方式一样,value序列化方式不一样便会导致其中一个服务在取值时出现异常。
方案:尽量避免在复用redis时,key冲突,即使k-v相同也要对序列化方式进行确认。
服务缩容
服务缩容主要是对应服务器缩容下线,则需要进行摘机进行。
对于服务下线,要像每次上线一样谨慎再三,因为涉及到的依赖服务、中间件、待释放的实例,都随时可能影响到其他在线上正在稳定运行的服务。
结语
以上所做的全部服务下线操作基本都是为了确保下线时不影响到其他服务,以及使整个下线过程是可逆的,即使在下线后再要求上线也能在较短的时间内完成服务再次完整上线,以防止出现的更多风险。