背景介绍
微医搜索系统历经多年,现已形成6个主系统、近百台服务器、2019年月均发布十多次的规模,solr的版本也跨越了4.x ~ 8.x,涉及近200个collection,几百个接口。
如下图所示,搜索系统包含solr、索引任务、接口服务三个主要模块,每个模块中又包含了不同的操作,而所有模块间又有着执行顺序要求,执行顺序错误,就会出现异常。
所以,搜索系统是一个复杂度相当高的系统,包括复杂的发布和部署方式,复杂的发布方式在发布的时候会导致系统的稳定性受到较大的影响,效率也不高。在发布频率越来越高的情况下,保证发布的效率及稳定性,是发布系统的首要目标。在此基础上,为了进一步提高发布的效率,我们提出了搜索系统一键发布的目标,就是一条命令完成所有系统的线上发布部署。
发布系统演化史
发布系统 v1.0
最初的发布,没有几十台服务器,也没有那么高的发布频率,发布流程是手工操作,拉代码,重启任务,切换目录一气呵成,重复的工作在机器数量不多的情况下,显得并不繁琐。但随着系统的拆分,功能的增加,人工发布也撑不住了,发布需要变得更高效。
发布系统 v2.0
随着业务的增长,搜索系统的服务器也变得多了起来,近30台服务器,如果仅靠手工发布,估计每次都要发到后半夜了,如何将发布自动化成了当前最大的问题。
是自己实现远程执行命令?还是用第三方工具?用什么工具?经过多次的调研,我们选择了fabric,fabric可以将本地命令和远程命令完美的组织起来,可以通过环境变量env
将本次发布的所有服务器一同发布。还支持不同配置文件,使测试环境和开发环境也可以自动化发布。
什么是fabric?
- 一个让你通过命令行执行无参数 Python 函数的工具
- 一个让你通过 SSH 执行 Shell 命令更加容易、更符合 Python 风格的命令库
fabric实现起来也很容易,只需要一个配置文件,一个发布脚本,通过几个参数就可以控制每次发布的服务器。2.0版本实现了每次发布只需要执行一条命令,只需关注屏幕输出,各系统的准自动化发布,不需要发布到后半夜,不用担心手动执行的命令是否准确,进一步提高了发布的效率及稳定性。
发布系统 v3.0
轻松的发布过程持续了一段时间后,搜索系统又扩大到了5个系统,近50多台服务器,之前的2.0发布系统又变得耗时耗力,每次发布需要的人越来越多,时间也变得更长,而问题主要集中在以下几点:
- 由于有一个系统的solr版本较低,该系统的master节点需要手动发布。
- 但不同系统的发布脚本都在各系统的代码目录下,每次发布时,都需要checkout一遍当前系统的代码。
- 每个系统的发布命令、发布脚本、参数各有不同,新员工学习发布时,每个系统都需要了解一遍。
- 发布过程都需要紧盯屏幕,避免发布过程出现异常。
- 每次发布时,不同系统的发布人员都需要主动在群里同步发布进度,如果中间出现异常,其他人也不能在第一时间协助解决。
- 每次发布结束如果出现问题,不能提前知晓,总是过一段时间才能发现问题。
3.0版本中,将该系统master节点的发布融合进自动化发布脚本中,实现全系统自动化发布。将所有的发布脚本抽取至公共包的一个目录中,发布时只需要更新一遍代码即可。将所有发布命令整合成一条发布命令,降低的发布的学习成本,提高了效率。将发布过程中的异常都会捕获,在发布结束时会统一输出提示发布人员。做到了发布信息自动同步到钉钉群中,异常信息也会同步,其他人员能够及时的获取到发布进度,并且发布信息还会同步写入数据库,串联起每次每个系统的发布过程,日后也能统计出发布频率等信息。融合了基准测试,在发布指定节点时,会进行基准测试,提前获取到发布时的异常。
经历了3个版本的迭代,发布系统解决了代码不统一问题、信息同步问题、发布后自动化测试问题,实现了全自动化发布,让发布不在提心吊胆。
发布系统 v4.0
经过了2.0到3.0的质变,搜索系统也在快速的扩大,达到了6个主系统,近百台服务器,且随时都又裂变的可能,4.0的任务也越来越艰巨,实现一键发布且能快速支持系统裂变。为了实现这一目标,有两个优化方向,一种是基于微服务的思路改造现有搜索架构,一种是基于调度的思想快速实现一键发布。
方案一:搜索微服务
文章开始便介绍了搜索系统由solr系统、索引服务、接口服务三大模块组成,随着搜索系统的扩大,单系统的功能需被拆分,使各个模块独立。确定系统应如何拆分,首先要了解当前系统承担了哪些职责以及在发布时需要做什么操作,单系统发布时,主要分为三种操作:solr配置更新、索引服务重启、接口服务重启,所以,单系统可以拆分成三个部分:
- solr服务:该服务仅为solr集群,可以搭建如下solr后台管理系统,来进行solr配置更新操作,在发布时,可将此步骤在发布前操作,提前更新schema配置,避免发布时更新错误造成异常。
- 索引服务:索引系统只负责搜索索引的更新任务:全量、增量、实时任务。发布时仅依赖于solr服务,当solr配置就绪时,可直接发布,不会影响其他服务
- 接口服务:接口服务只提供搜索接口调用服务,无需与solr、索引同时发布,使发布更加轻量。
当每个系统更加轻量,发布过程也会变得更加稳定而高效。
方案二:发布调度系统
目前的搜索机器节点,主要分为三种角色:
- master节点:运行索引更新任务,不提供接口服务
- 实时节点:只运行实时索引任务,不提供接口服务
- 其他节点:只提供接口服务,不运行索引任务
所以,在每次发布时,都需要按如下顺序发布:
当前的发布脚本,已经实现了单次发布的一键发布,而缺少的是单系统发布时,将多次发布的参数及顺序整合起来,并且控制每次命令的执行间隔时间。
所以,可以提前收集发布参数及发布后需要执行的命令,写入配置文件或数据库,再通过调度脚本,将单系统的完整发布流程按指定的时间间隔顺序执行即可。
在实现了单系统一键发布后,基于同样的思路,也实现了全系统的一键发布,最终,每次发布只需一人,甚至不需要人全程关注,只需要在异常时及时解决即可。
微服务化是当一个服务发展到一定规模时必须要考虑的事情,但快速实现一键发布能更快的提高发布效率,并且在搜索微服务化后,也能快速的提供发布支持。所以,最终我们选择了方案二实现搜索全系统一键发布。即使搜索系统未来再扩大一倍,发布系统也能快速支持且能保证效率及稳定性。
总结
总的来说,发布系统经过了几个版本的发展,从最初的手动发布到全系统一键发布,从发布时需要多人到只需一人,从发布至深夜到早早发布结束,从发布提心吊胆到发布预案完备。发布系统可以说是历经巨变,效率和稳定行都有着显著的提高,而通过对发布脚本的优化,也对整个搜索系统优化提供了方向,作为搜索系统的一部分,高效的发布能够节省出更多开发人员的时间,让时间用在刀刃上。