基于JenKins实现实时业务系统的不中断上线
2021-10-15赖正华
赖正华
(中移信息技术有限公司,广东 深圳 518048)
1 引言
现在很多的业务系统引用微服务化的思想,将业务系统的功能在应用程序实现上进行解耦处理:每个功能由单独的程序模块来提供,再将各个程序模块,利用消息队列的形式串联起来。假如应用程序分为了前置程序、业务处理程序。前置程序接受请求后,通过MQ消息中间件将消息通过点对点的方式分发到业务处理程序。业务处理程序根据不同的请求渠道以及用户归属省等因素,可将消息引流到不同的业务处理程序去消费消息,比如对业务量很大的省份或者渠道,由A主机单独提供服务,对业务量小的省份或者渠道可以多个省或渠道共享一台主机消费消息,利用MQ的点对点消息,实现了流量的分流。因此,在代码打包编译时,需要对不同的业务处理节点标识不同的appcode,每一个tomcat运行单独标识appcode的业务处理war包程序,这样便可实现点对点消息消费。由于承载的是全网的业务,部署的服务器数量和tomcat容器数量会达到数十个,且随着业务规模的发展,服务器的数量一直在增长,因此在每次进行变更上线时,运维人员的工作强度和压力越来越大。且系统属于实时交易类系统,为在全球漫游的用户提供无间断的服务,对系统变更上线提出了高要求:需要不间断提供服务且快速又准确地完成变更上线操作。本文将对这种业务场景的系统上线方式展开研究。
2 技术选型比较
目前行业内用于自动化上线的开源工具有Ansible、Saltstack、Jenkins等。
Ansible是一种基于Paramiko开发的自动化运维工具。通过SSH协议与远程主机相结合,并以模块化的方式实现批量部署、自动化执行命令等功能。基于Ansible可以实现批量的操作,比如对批量的tomcat进行停启操作,对批量的tomcat下的webapp目录替换相同的war包程序,但Ansible不适合这种业务场景:系统涉及有数十个tomcat节点,每个节点运行的war包程序不同,因此Ansible工具无法实现对这数十个运行不同war程序的tomcat进行批量的操作。
Saltstack也是类似的情况,只能对相同的命令执行批量操作,不适合这种不同主机的操作命令不同、变更上线的程序版本不同且涉及的主机数量众多的业务场景。
Jenkins是一款开源CI&CD软件,用于自动化各种任务,包括构建、测试和部署软件[1]。本文基于Jenkins的Publish Over SSH插件实现将上线程序从Jenkins服务器分发到应用主机,并执行shell脚本实现变更上线的流水线操作:应用程序备份、停tomcat进程、删原来的程序文件、移新版本程序文件到指定目录、更改配置文件、启动tomcat进程、检查进程是否启动等操作。
3 基于Jenkins的方案设计
本文将基于Jenkins设计一种方案,可实现实时交易系统的不中断上线。首先,若需要实现业务系统的不中断上线,需要对业务系统的部署进行重新设计,原来的业务系统由前置程序写消息到消息队列中,业务处理节点从MQ服务器监听并拉取消息处理,而且是采用点对点的消息队列模式,如果未采用主备的模式部署,那么在变更上线时,需要重启tomcat操作,消息没有消费者来消费,此时会导致业务中断。现在改为部署主备式的业务处理,打包编译时,对war包加上标签appcodeA和appcodeB,两个业务处理节点都监控消息队列A,都可以从这个队列拉取消息处理,两个tomcat都可以监听这个消息队列A,实行抢消息的方式去消费消息。其他的业务处理节点也做类似的部署调整,这样业务系统在MQ的作用下,实现了分布式的部署,且每个业务处理、前置程序都具备了主备节点,如图1所示。这样在日常的变更操作时,如果对主节点进行重启操作的时候,消息队列A的消息可以被备tomcat节点进行消费,正常提供对外访问,实现业务不中断。但随之带来的是tomcat数量的翻倍。
图1 业务应用分布式化部署
在对应用系统进行了部署优化后,在Jenkins管理界面,添加远程主机;然后对每一个tomcat配置一个job任务,在job任务的配置界面编写远程执行的shell命令。按照上线操作的流水操作编写shell命令。当触发这个任务时,能单独完成这个tomcat节点的进程启停、文件备份与换新等操作。
在对所有的主节点配置完成job任务后,将所有的主节点job加入到一个新的job中,如图2所示。
图2 主备节点job列表
同理对所有的备节点,每个节点配置一个job任务,在job任务中配置对应的shell命令,实现各个节点可以个性化地操作tomcat。将所有的备节点job加入到新的一个job中,任命为BUSI-BACK,如图2所示。这样便可以将所有的主节点归纳到一个job,所有的备节点归纳到另一个job,可实现并发操作。
在上线变更操作时,依次对主节点的控制任务BUSIMAIN触发工程构建操作,如图3所示,此时所有主节点的tomcat会并发的进行上线操作,极大地缩短上线变更时间。此时,备节点的tomcat从消息队列读取消息进行消息处理,对外表现为业务未中断。在主节点完成上线变更操作后,再对备节点进行工程构建操作,此时主节点的所有tomcat从消息队列拉取消息进行业务处理,对外表现也是业务不中断。
图3 主备节点的控制job列表
4 方案实现:Jenkins配置与shell编写
首先在部署主机运行Jenkins服务:nohup java-jar jenkins.war--httpPort=8080&。在浏览器输入Jenkins的访问界面:http://localhost:8080,按照提示输入密钥后即可进入Jenkins服务的管理界面[2]。
Jenkins具有可伸缩的插件机制,集成人员可以很方便地进行配置的自主性选择,根据自己所需要的插件进行安装、删除和添加。进入到首界面的系统管理界面后,再进入到插件管理界面,本文的方案需要安装Publish Over SSH插件包,在生产环境需要采用离线安装的方式[3]。
接下来是新建job的工作,即如图2所示的BN-S-001即为一个独立的job。在界面中进行配置和shell命令编写工作。在配置界面中,需要配置目标主机的信息,即job的名称,需要配置上线文件的source files的正则表达式,在本文中配置为*,即匹配任何的文件,本文中默认所有的主节点命名为BN-S-00*,备节点则命名为BN-S-10*。在本文中将实现对一个tomcat进行如下流水线式的操作:备份原webapps目录下的程序文件、kill tomcat进程、休眠一段时间待tomcat完成上一笔业务、再次kill tomcat进程、删除原webapps目录下的所有war包程序和war包解压后的程序文件、删除配置文件、将要上线的新程序war包文件拷贝到webapps目录下、拷贝新的配置文件到配置目录下、启动tomcat进程。每一个tomcat都需要进行类似的流水操作。
实现的shell脚本如下:
在每个job中都完成上述的job配置,以及把shell命令拷贝到每个job的command窗口中便可完成配置[4]。配置完成后的效果如图2所示。
5 测试与应用
将所有的BN-S-00*开头的job作为主节点编排在BUSIMAIN这个job中,将BN-S-10*开头的job编排到BUSIBACK这个job中作为备节点。对BUSI-MAIN这个job点击构建操作,即可触发这个job下的所有主节点job进行并发的构建,所有的job并发的执行shell命令,完成流水线式的操作。在对BUSI-MAIN这个job完成构建的时刻,tomcat是不提供对外服务的,此时作为备节点的BN-S-10*节点均正常对外提供服务。在BUSI-MAIN这个job完成构建后,即完成了新版本上线后,再对BUSI-BACK这个job进行相同的操作,此时主节点对外提供服务,如图4所示。经过实测,单人对55个tomcat进行正常的变更上线操作,需要花费的时间在2个小时以上,但利用本文的方案实现,可在5分钟内完成上线工作,不中断业务系统的服务,且可大大降低人为错误操作的风险。
图4 测试结果
6 结语
本文针对实时交易业务系统在进行不中断业务变更上线提出了一种解决方案。适用的业务场景为每个tomcat或者其他容器所承载的应用程序版本不同,但又需要批量上线的情况。利用Jenkins可定制化地实现每个tomcat或容器实现不同的流水线操作,最终进行搭积木式的组合调用。本文结合业务系统的部署情况,对部署进行了优化改进,以实现变更上线过程不中断业务的功能[5]。经过实测,该方案能极大提高上线的效率和准确度。