Jenkins为什么一直调度到同一个节点

1. 问题背景

3.1 采用多流水线多业务的设计

如上图,每个业务创建一条流水线,在构建数量相同的情况下。原来的 1 条流水线 10000 条构建历史,改进为 100 条流水线,每条流水线 100 条构建记录。这在查询性能上,会带来显著提升。同时,给调度策略提供了更大灵活性。可以给部分流水线指定特定的构建节点,保障高优先级的业务具有更高的可用性。

3.2 添加更多的构建机、减少单个节点的并发数量

通常,为了更充分的利用构建机资源,我们会将节点的并发数量设置得很高,比如 50、100。由于 Jenkins 的调度策略,在单流水线多业务的设计下,Job 会集中到某一个节点,造成压力。因此,我们可以增加构建机的数量,而减少单个节点的并发数量。之前是单个节点并发最大 50,现在可以降低配置,使用 3 台低配的构建机,使用相同的标签,并发设置为 20。这种方式是在物理上对构建环境进行了隔离,提高整个流水线系统的可用性。

3.3 使用 Throttle Concurrent Builds 插件控制并发

插件离线下载地址: https://archives.jenkins-ci.org/plugins/throttle-concurrents/ ,直接上传不用重启即可生效。Throttle Concurrent Builds 插件主要用来对并发构建数量和策略进行控制。在 Jenkins 的配置页面,可以设置最大总的构建数量、每个节点最大构建数量。在每条流水线中,可以设置指定时间间隔内的构建数量。这种方式主要是通过限流的方式,保证服务的可用性,避免业务量超过系统设计值时,导致流水线不可用。但缺陷也很明显,就是业务量大时大量流水线处于等待状态。

3.4 将节点选择也作为流水线参数

在上面的模型中,多个业务公用了一条流水线,而流水线对节点的选择使用的是同一个标签,也就是将调度完全交给了 Jenkins。这是导致上述问题的根源之一。因此,我们可以在业务系统中,维护一个可用的标签列表,每次创建 Job 时,随机提供一个有效的标签,控制 Job 选择指定的节点进行构建。这种方式是通过业务系统的控制,指定构建机来控制 Job 在构建机上的均衡分布。

3.5 使用 Kubernetes 提供构建环境

利用 Kubernetes 提供的弹性,在 Kubernetes 上动态创建 Jenkins Slave,可以具有很高的并发量,可以参考在 Kubernetes 上动态创建 Jenkins Slave、Kubernetes 动态创建 Jenkins Agent 压力测试。

4. 总结

本文主要针对流水线遇到的调度和并发问题,进行了分析并给出了几种解决方案。其中建议:
  • 使用多业务多流水线的模型
  • 添加更多的构建机分散构建
  • 设置构建机能承受的并发值
  • https://archives.jenkins-ci.org/plugins/throttle-concurrents/latest/
  • https://nagle.top/2020/11/02/Jenkins-Queue-Arch.html
  • https://www.cnblogs.com/guguli/p/7827435.html