vivo 自研Jenkins资源调度系统设计与实践
作者: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工具后期进行容器化、池化,在提高资源利用率和发布效率的同时也可以为用户提供可靠的、简洁的、稳定调度执行。
vivo 自研Jenkins资源调度系统设计与实践的更多相关文章
- vivo 商品中台的可视化微前端实践
一.背景 在电商领域内,商品是一个重要组成部分,与其对应的商品管理系统,则负责商品的新建.编辑.复制等功能.随着商品管理系统的成熟稳定和业务上的扩展需求,催化出了商品中台的诞生.它可以将现有商品功能最 ...
- vivo大数据日志采集Agent设计实践
作者:vivo 互联网存储技术团队- Qiu Sidi 在企业大数据体系建设过程中,数据采集是其中的首要环节.然而,当前行业内的相关开源数据采集组件,并无法满足企业大规模数据采集的需求与有效的数据采集 ...
- Java生鲜电商平台-SpringCloud分布式请求跟踪系统设计与实践
Java生鲜电商平台-SpringCloud分布式请求跟踪系统设计与实践 Java生鲜电商平台微服务现状 某个服务挂了,导致上游大量报警,如何快速定位哪个服务出问题? 某个核心挂了,导致大量报错,如何 ...
- vivo 云原生容器探索和落地实践
作者:vivo 互联网容器团队- Pan Liangbiao 本文根据潘良彪老师在"2022 vivo开发者大会"现场演讲内容整理而成.公众号回复[2022 VDC]获取互联网技术 ...
- 持续集成高级篇之Jenkins资源调度
系列目录 之前的示例我们主要关注点在于功能的实现,都是在一个节点的完成了.有了多个节点后,必须涉及到资源的调度问题.本节我们讲解在创建任务时与资源调度的有关选项以及一些平时没有注意到的但在生产环境需要 ...
- 一文看懂 K8s 日志系统设计和实践
上一篇中我们介绍了为什么需要一个日志系统.为什么云原生下的日志系统如此重要以及云原生下日志系统的建设难点,相信DevOps.SRE.运维等同学看了是深有体会的.本篇文章单刀直入,会直接跟大家分享一下如 ...
- vivo 服务端监控架构设计与实践
一.业务背景 当今时代处在信息大爆发的时代,信息借助互联网的潮流在全球自由的流动,产生了各式各样的平台系统和软件系统,越来越多的业务也会导致系统的复杂性. 当核心业务出现了问题影响用户体验,开发人员没 ...
- vivo互联网机器学习平台的建设与实践
vivo 互联网产品团队 - Wang xiao 随着广告和内容等推荐场景的扩展,算法模型也在不断演进迭代中.业务的不断增长,模型的训练.产出迫切需要进行平台化管理.vivo互联网机器学习平台主要业务 ...
- 基于GitLab+Jenkins的DevOps赋能实践
随着微服务.中台架构的兴起,DevOps也变得非常关键,毕竟是一些基础设施层面的建设,如果搞好了对后面的研发工作会有很大的效率提升.关于DevOps本身的概念,网上已经非常多了,在园子里随便搜索一些都 ...
- 从自动化到智能化,网易杭研的AIOps探索与实践
在大数据时代下,我们借助机器学习.数据仓库.大数据平台等大数据技术手段,将运维产生的数据进行分析.处理,得出最佳运维策略,以期实现对故障的事先干预,将风险降低到最低,从而降低运维成本,提升运维效率,最 ...
随机推荐
- 【深入浅出 Yarn 架构与实现】3-3 Yarn Application Master 编写
本篇文章继续介绍 Yarn Application 中 ApplicationMaster 部分的编写方法. 一.Application Master 编写方法 上一节讲了 Client 提交任务给 ...
- K8S kubesphere安装mysql
原先我们使用Docker按照mysql时候的命令 docker run -p 3306:3306 --name mysql-01 \ -v /mydata/mysql/log:/var/log/mys ...
- 手动安装Mysql数据库,适合重装系统和绿色安装。
依次输入命令: d:cd D:\MySQL Server 5.6\bin 根据自己的目录设置 mysqld --install mysql4001 --defaults-file="D:\m ...
- CmakeLists简单使用总结
单文件工程和多级目录工程CmakeLists.txt编写分享 你若发现该帖中有待商榷的地方,还请指正赐教,先行拜谢了! 1 main.c单文件工程CmakeLists.txt 1.1 目录结构 1.2 ...
- Jmeter——结合Allure展示测试报告
在平时用jmeter做测试时,生成报告的模板,不是特别好.大家应该也知道allure报告,页面美观. 先来看效果图,报告首页,如下所示: 报告详情信息,如下所示: 运行run.py文件,运行成功,如下 ...
- NOIP 口胡
因为没准备啥东西 这两天口胡一下近年 NOIP 的题 大概会一道不落?没什么很寄的考点主要是 2021 T1 报数 打一个 \(O(\log n)\) 查询 \(n\) 中是否有 \(7\),打一个类 ...
- 3.5:基于Python的KNN算法简单实现
〇.目标 1.使用pycharm工具创建项目demo: 2.使用python语言实现KNN算法. 一.创建脚本文件 二.编写KNN算法程序 KNN算法所阐述的核心思想在KNN.py文件的注释部分具有详 ...
- 【每日一题】【迭代器,泛型】2022年1月8日-NC93 设计LRU缓存结构
描述设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 k ,并有如下两个功能1. set(key, value):将记录(key, value)插入该结构2. get(key): ...
- (四) 一文搞懂 JMM - 内存模型
4.JMM - 内存模型 1.JMM内存模型 JMM与happen-before 1.可见性问题产生原因 下图为x86架构下CPU缓存的布局,即在一个CPU 4核下,L1.L2.L3三级缓存与主内存的 ...
- Django框架模板语法传值-过滤器-标签-自定义过滤器,标签,inclusion_tag
目录 一:模版语法传值 1.模板语法两个书写方式 2.模板语法 3.测试模板语法是否可以把python支持的基本数据类型传入到前端 4.index.html 5.django模板语法取值方式 二:过滤 ...