作者:vivo 互联网服务器团队- Wu Qinghua
本文从目前业界实现Jenkins的高可用的实现计划,剖析各计划的优缺点,引入vivo目前应用的Jenkins高可用计划,以及目前Jenkins资源的调度计划的设计实际和目前的落地运行成果。
一、前言
当初的企业很多都在用Jenkins做继续集成,各个业务端都依附Jenkins,vivo Devops也是应用Jenkins来进行继续构建,部署Jenkins服务时如何保障服务的高可用变得尤为重要。
上面是目前Jenkins存在的一些问题。
- Jenkins自身是单体的,即只能有一个Jenkins Master。尽管你也能够在多台机器上部署多个Jenkins Master,但这些Master之间没有分割,都是各自把工作交给手下的slave去执行,没有任何交加。兴许某个master下的slave很忙,而另一个master下的slave却很闲,资源得不到充分利用。
- 当其中一个slave宕机之后,该slave上的运行的job工作没有版本从新进行调配,须要用户从新执行。并且slave节点离线之后没有告诉管理员。
- 当零碎业务量比拟大的时候业务申请集中在Jenkins Master上,会对Jenkins造成压力,甚至的造成Jenkins服务不可用。
- 当有job工作在jenkins Master上队列排队的时候,Jenkins Master宕机后,队列工作不可长久化。
- Jenkins Workspace没有主动清理性能,会导致磁盘空间有余,工作执行不了的状况。
基于以上状况,vivo Devops对Jenkins的部署架构进行优化搭建,并且配套了一套Jenkins资源调度零碎用于治理Jenkins资源。
二、业界实现
目前业界也蕴含一些Jenkins 高可用的设计形式,然而并不能齐全的满足解决上述问题,比方:
2.1 计划一 Gearman + Jenkins
这是OpenStack团队应用的计划。这个计划应用了gearman, gearman是个工作散发框架。
须要在每个Master上装置好gearman的插件,并配置好能连贯到gearman server,同时在每个Master必须建设雷同的job。
之后运行工作的流程如下:
- gearman worker运行在各个Jenkins Master中期待gearman server散发工作;
- gearman client向gearman server收回运行job的申请;
- gearman server告诉各个gearman worker有工作拉,第一个闲着的worker会接受任务,如果所有的worker都忙,则放入gearman的工作队列,得worker闲暇时再调配;
- gearman worker闲下来后会从工作队列里取job来执行,执行完之后,将后果发回给gearman server;
- gearman server将后果返回给 gearman client。
长处:
这样各个salver资源能够失去充分利用,某个master挂掉另外的master能够持续服务。
弊病:
每个master的slave必须配置统一,否则会造成job调度谬误,同时会造成一些资源的节约。当一个master呈现问题,该master的工作不会进行主动重新分配。
2.2 计划二 革新Jenkins的文件存储形式
目前Jenkins的配置文件都是间接在硬盘上以文件模式存储的,你在JENKINS_HOME的个文件夹下能看到各种.xml文件。有些公司在Jenkins上进行二次开发,将Jenkins的数据存储形式改为数据库存储,这样前端能够起多个Jenkins服务,后端连雷同的数据库即可。数据库也有比拟成熟的高可用计划。
长处: 能够达到Jenkins的高可用也就是某个master挂掉另外的master能够持续服务。
弊病:须要对Jenkins进行二次开发,应用数据库会升高读取资源效率降落。
2.3 计划三 最简略的Jenkins一主一备模式
平时让Jenkins A机器提供服务,并应用SCM Sync configuration plugin保留数据,JenkinsA机器批改配置后触发Jenkins B更新配置,一旦Jenkins A呈现问题挂掉后,切换到备机Jenkins B上。
长处: 能够达到Jenkins的高可用,当master宕机后会进行切换到备机上。
弊病: 会有一批Jenkins备机存在资源节约,切换master工夫过长,会导致有段时间Jenkins服务不可用。
三、vivo Jenkins Scheduler零碎指标
因为目前业界的一些实现还不能齐全的满足咱们目前的需要,所以咱们进行了vivo jenkins scheduler零碎的设计与实现。该零碎须要达到如下的目标:
晋升整个构建服务可靠性时长。
保障jenkins集群的高可用,解决目前master-slave的单点问题,保障整个构建服务的可靠性时长。
升高劫难时服务复原时长。
①提供精准流控形式,在jenkins构建呈现申请量过高的时候能够进行流控和长久化操作,缩小对目前零碎的冲击。
②当零碎压力缩小后,放开流控能够疾速的对沉积的申请进行调配执行。
- 无效分配任务至各个子节点,保障资源的无效利用。
- 能保障劫难时的及时切换工作至可用节点上,同时能疾速的告诉管理员进行解决。
- 能进行数据的可视化剖析,能提供一系列帮忙改善开发效率的视图,比方构建时长报表、构建量报表等。
四、 vivo Jenkins Scheduler设计
该零碎咱们从两大部分进行了设计,首先,咱们不采纳原生的Jenkins部署计划,而是采纳全master的形式。第二,设计并开发了一套用于治理Jenkins集群的调度零碎。
五、底层 Jenkins 工具部署计划
不采纳目前单master的搭建计划,采纳多master的搭建计划,master下不进行挂载slave机器,工作间接有master进行解决,master之间的关系、任务分配、离线、插件装置等由调度零碎进行治理。这样因为vivo Jenkins Scheduler零碎为高可用的,解决了目前Jenkins的单点问题。
六、零碎架构图
七、零碎阐明
7.1 API-Gateway
次要提供零碎的内部申请,网关零碎,性能蕴含:
- 权限校验:校验用户发送集群管理系统的申请的权限。
- 智能路由:接管内部所有申请,并转发到后端的外服下来。
- 限流:与监控线程配合(当构建申请达到某个阈值时),进行限流操作。
- API日志对立收集:相似于一个aspect切面,记录接口的进入和进来时的相干日志。
- 数据处理:对申请的参数进行数据的转换解决。
7.2 事件核心
是整个零碎通信调用的次要模块,采纳的是Spring的Event机制实现,次要外围事件如下:
Jenkins注册事件
(EVENT\_REGIST\_JENKINS):
Jenkins启动后,通过自定的插件会向零碎发送注册申请时,零碎接管到后会触发Jenkins治理模块将Jenkins的信息注册至调度零碎中。
Jenkins宕机事件
(EVENT\_DOWN\_JENKINS) :
监控治理轮询查看Jenkins状态,当发现有Jenkins宕机的状况会触发该事件,Jenkins治理模块解决将Jenkins的信息状态设置为不可用状态,从而是工作不能调配至该台jenkins。
工作从调配事件 (EVENT\_JOB\_REDO) :
当Jenkins宕机后,如果该台jenkins上存在未执行完的工作时候,由job监控模块触发,job治理莫管解决,会对该Jenkins上未执行的job进行重新分配。
工作承受事件 (EVENT\_JOB\_RECIVE) :
当job治理模块承受到创立申请,会触发该事件,由job治理模块放入Redis执行队列。
工作执行事件 (EVENT\_JOB\_EXECUTE) :
job治理模块中的执行线程(10s执行一次,会从Redis队列中弹出工作),弹出工作后触发该事件,由调度核心选取适合的jenkins进行执行。
7.3 调度核心
是整个零碎的外围模块,次要的性能是进行执行job时候能选取适合的jenkins进行解决工作,蕴含两个外围算法:
7.3.1 Jenkins分组算法
每台Jenkins都能够应用标签的形式,打上多个标签,比方Jenkins能够构建Java程序,应用的构建工具能够是maven和gradle,这个时候咱们就能够给其打上Java、maven、gradle三个标签。
标签的维度次要有以下几个:
- 标签配置: 判断构建配置是否配置了标签,依据标签抉择对应标签的Jenkins,比方配置了(docker等)。
- 构建语言: 依据构建配置的语言,比方Java、C++、Python、Go等。
- 构建工具和版本: 比方Maven、gradle、Ant,Cmark、Blade等。
- JDK版本:比方JDK7、JDK8等。
- Go语言版本:比方1.15.x.、1.16.x等。
- GCC版本:如6.x、4.x等。
- Python版本:2.x、3.x等。
- 是否存活:判断Jenkins是否存活,如果宕机间接过滤。
- (可选策略)抉择执行过该job的Jenkins,缩小下载代码的过程:(第一次构建还是会比较慢,能够采纳预执行的形式,在配置构建配置的时候,就事后执行一次,这样在用户执行的时候就应用该job执行过得workspace,缩小代码下载的工夫)。
- (可选策略)依据job的构建的均匀构建时长,如果构建时长达到某个配置阈值时,优先选择构建器闲暇多的Jenkins进行执行,并指出Jenkins的锁定性能。其余的job不容许调配上来。
如果咱们给Jenkins打上标签,那么咱们就能够应用标签为维度将Jenkins进行分组,并且存入至Redis中缓存,不便后续选取Jenkins用来执行工作:
7.3.2 Jenkins选取算法
当Jenkins分组好了后,咱们承受到执行的job的信息就能够应用Jenkins选取算法进行疾速的选取适合的Jenkins进行解决job,如下图所示。
其中label子线程、语言子线程……就是咱们下面的Jenkins分组的维度,有多少维度,那么这里就会有多少子线程解决。
构建工作进入主线程,而后主线程会依照分组维度分组操作并进行过滤,而后获取到每个分组中适合的Jenkins,再进行取交加(这个时候就获取到能够执行该构建工作的Jenkins了),在判断是否须要通过可选策略,最终失去Jenkins。
7.4 流控治理&队列治理
调度零碎中的的工作承受采纳的是队列的形式实现,当零碎申请量达到阀后,零碎将不会进入Redis队列,会将申请长久化至MySQL。后续如果有申请过去,job治理模块会查看数据库MySQL中是否有申请,如果有申请,会将申请放入Redis队列,如果没有申请就会将以后申请放入Redis队列,具体流程如下:
其中基于Redis实现的音讯队列的时序图如下:
7.5 回调核心
该模块次要是监控工作的状态,当工作开始执行、中断执行、执行胜利、执行失败的时候进行告诉业务并存储数据,用于保留构建记录,不便后续数据的统计,用来实现数据的可视化。
八、施行成果
目前该零碎曾经投入生产环境运行,Jenkins工作已采纳调度零碎进行调度执行,运行稳固,运行成果。
九、后续瞻望
随着vivo Jenkins 调度零碎的性能缓缓欠缺,Jenkins的机器也越来越多,目前还大多数运行在虚拟机上,从资源利用率和业务公布效率来看,将来的业务公布状态将会是以容器为主。目前公司也在大力发展k8s的容器生态建设,
所以咱们心愿将Jenkins工具前期进行容器化、池化,在进步资源利用率和公布效率的同时也能够为用户提供牢靠的、简洁的、稳固调度执行。