管道最佳实践

本指南为管道提供了一小部分最佳实践,并指出了最常见的错误。

目标是将管道作者和维持者指向导致更好的管道执行,并远离陷阱的模式,否则他们可能不知道。本指南并不意味着是所有可能的管道最佳实践的详尽列表,而是提供许多有用的特定示例,可用于跟踪常见实践。用它作为“做到这一点”,而不是一个令人难以置信的详细的“how-to”。

本指南由区域,指南,然后列出特定示例排列。

一般的

确保在流水线中使用Groovy代码作为胶水

使用Groovy代码连接一组操作而不是作为管道的主要功能。换句话说,而不是依赖流水线功能(Groovy或管道步骤)来向前驱动构建过程,使用单个步骤(例如SH.)完成构建的多个部分。流水线,因为它们的复杂性增加(Groovy代码的数量,所使用的步数等),需要更多的资源(CPU,存储器,存储)。将管道视为实现构建而不是构建核心的工具。

示例:使用单个Maven构建步骤通过其构建/测试/部署进程来驱动构建。

在管道中避免复杂的Groovy代码

对于管道,Groovy代码总是在控制器上执行,这意味着使用控制器资源(内存和CPU)。因此,减少管道执行的Groovy代码的量非常重要(这包括在管道中导入的类上的任何方法)。以下是最常见的例子避免使用的方法:

  1. JSonslurper:此函数(以及与XMLSlurper或ReadFile这样的其他类似的函数)可用于从磁盘上的文件读取,将数据从该文件解析为JSON对象,并使用像JSonsLurper()等命令将该对象注入管道中。Parsetext(ReadFile(“$ local_file”)))。此命令将本地文件加载到控制器上的内存中两次,如果文件非常大或命令频繁执行,则需要大量内存。

    1. 解决方案:而不是使用JSonslurper,使用shell步骤并返回标准。这个shell看起来像这样:def jsonreturn = sh标签:'',returnstdout:true,脚本:'echo“$ local_file”|JQ“$ parsing_query”'。这将使用代理资源来读取该文件,$ parsing_query将帮助将文件解析为较小的尺寸。

  2. httprequest:通常,此命令用于从外部源抓取数据并将其存储在变量中。这种做法并不理想,因为如果控制器没有加载证书,则不仅可以直接来自控制器(这可能会给HTTPS请求等内容提供错误的结果),还存储对该请求的响应量是两次。

    1. 解决方案:使用shell步骤从代理执行HTTP请求,例如使用刀具卷曲或者w, 作为适当的。如果结果必须在管道中稍后,请尝试尽可能多地过滤代理侧的结果,以便仅将最小所需信息传输回Jenkins控制器。必威国际有限公司

减少类似管道步骤的重复

将管道步骤与单个步骤相结合,尽可能频繁地减少由管道执行发动机本身引起的开销量。例如,如果您运行三个shell步骤后退,则必须启动和停止每个步骤,要求创建和清理代理和控制器上的连接和资源。但是,如果将所有命令放入单个shell步骤中,则只需启动和停止单个步骤。

示例:而不是创建一系列回声或者SH.步骤将它们组合成一个步骤或脚本。

避免呼叫必威国际有限公司jenkins.getInstance.

使用Jenk必威国际有限公司ins.Instance或其访问者方法在管道或共享库中,指示该管道/共享库中的代码误用。使用jenk必威国际有限公司ins apis从一个不适合的共享库意味着共享库是共享库和某种jenkins插件。与Jenkins API从管道交互时,您需要非常小心,以避免严重的安全性和性能问题。必威国际有限公司如果您必须在构建中使用Jenki必威国际有限公司ns API,则建议的方法是在Java中创建一个最小的插件,该插件在jenkins API周围实现安全包装器,您要使用管道的步骤API访问。使用Jenk必威国际有限公司ins Apis从沙盒的Jenkinsfile直接意味着您可能不得不多白名单方法,允许任何可以修改管道的人绕过沙箱保护,这是一个重要的安全风险。白名单方法作为系统用户运行,具有整体管理员权限,这可能导致具有比预期的更高权限的开发人员。

解决方案:最佳解决方案是在所做的呼叫周围工作,但如果必须完成,那么更好地实现能够收集所需数据的Jenkins插件。必威国际有限公司

使用共享库

不要覆盖内置管道步骤

尽可能远离定制/覆盖管道步骤。覆盖内置管道步骤是使用共享库来覆盖标准管道API的过程SH.或者暂停。此过程是危险的,因为管道API可以随时改变,导致自定义代码破坏或给出不同的结果而不是预期的。当自定义代码因管道API而发生变化时,难以解决,因为即使自定义代码没有改变,也可能在API更新后可能无法运行。因此,即使自定义代码没有改变,也不意味着在API更新之后它将继续工作。最后,由于在整个管道中使用这些步骤,如果某些东西被编码错误/效率低下,结果可能对Jenkins造成灾难性。必威国际有限公司

避免大型全局变量声明文件

具有大量的变量声明文件可能需要大量的内存,几乎没有任何好处,因为对于每个管道来加载文件是否需要或不加载变量。建议使用仅包含与当前执行相关的变量的小变量文件。

避免非常大的共享库

在流水线中使用大型共享库需要在流水线启动和加载当前正在执行的每个作业的相同共享库之前检查一个非常大的文件,这可能导致内存开销和较慢的执行时间。

回答额外的常见问题解答

处理管道中的并发性

尽量不要在多个管道执行或多个不同的管道上共享工作空间。这种做法可能导致每个管道或工作区重命名内意外的文件修改。

理想情况下,共享卷/磁盘安装在单独的位置,并且文件将从该位置复制到当前工作区。然后,当构建完成时,如果完成更新,可以复制文件。

构建在不同的容器中,从头开始创建所需的资源(云类型代理为此工作很好)。构建这些容器将确保构建过程每次都开始于一开始,并且很容易重复。如果构建容器不起作用,则在管道上禁用并发性或使用可锁的资源插件在运行时锁定工作区,以便在锁定时无法使用其他构建。警告:禁用并发或锁定工作区运行时会导致管道当这些资源被任意锁定时等待资源时被阻止。

此外,请注意,这两种方法都具有比每个作业的独特资源的构建结果较慢

避免notserializableException.

管道代码是CPS转换,使得管道能够在Jenkins重新启动后恢复。必威国际有限公司也就是说,当管道运行脚本时,可以关闭Jenkins或丢失与代理的连接。必威国际有限公司当它恢复后,jenkins记得它在做什么必威国际有限公司,你的管道脚本恢复执行,就好像它永远不会中断一样。一种称为“延续传递风格(CPS)“执行在恢复管道中发挥着关键作用。但是,由于CPS转换,某些Groovy表达式无法正常工作。

在引擎盖下,CPS依赖于能够将管道的当前状态序列以及剩余的管道序列。这意味着在不序列化的管道中使用对象将触发anotserializableException.当管道试图持续其状态时要抛出。

管道CPS方法不匹配有关更多细节和可能存在问题的一些示例。

下面将涵盖确保管道可以按预期运行的技术。

确保持久的变量是可序列化的

在序列化期间捕获局部变量作为管道状态的一部分。这意味着在管道执行期间存储在变量中的非序列化对象将导致notserializableException.被抛出。

不要将非序列化对象分配给变量

一种利用非序列化对象的一个​​策略始终推断它们的值“即时”,而不是计算它们的值并将该值存储在变量中。

使用@noncps.

如有必要,您可以使用@noncps.注释为禁用CPS转换的特定方法,如果它是CPS转换的那样,其身体不会正确执行。只要意识到这也意味着Groovy函数必须完全重新启动,因为它没有转换。

异步管道步骤(例如SH.睡觉)始终是CPS转换,并且可能不会在用的方法内使用@noncps.。通常,您应该避免使用管道步骤注释的方法内@noncps.

管道耐用性

值得注意的是,改变管道的耐用性可能导致notserializableException.没有被扔在他们否则的地方。这是因为通过Performance_Optimized降低了管道的耐用性,意味着管道的当前状态持续得差异很大。因此,管道永远不会尝试序列化非序列化值,因此,没有抛出异常。

存在此注释,以告知用户此行为的根本原因。不建议将管道的耐用性设置设置为纯粹优化的性能,以避免序列化问题。



此页面有用吗?

请通过此提交您关于此页面的反馈快速形式

或者,如果您不希望填写快速表格,您可以简单地指示您是否找到此页面有用吗?


查看现有的反馈这里