解決 Jenkins 效能緩慢的問題

語言: CN / TW / HK

沒有什麼比緩慢的持續整合系統更令人沮喪的了。它減慢了反饋迴圈並阻止程式碼快速投入生產。雖然像使用效能更好的伺服器可以為您爭取時間,但您最終必須投資於維持持續整合工作流程的成本。

Jenkins 是目前最流行的 CI/CD 工具之一,但隨著時間的推移,使用者經常會遇到滯後和響應緩慢問題。在本指南中,我將分享一些 Jenkins 效能問題的概述,以及一些無需升級硬體即可顯著提高效能的技巧。

1. 為什麼 Jenkins 如此受歡迎的 CI/CD 選擇?

Jenkins 是一種基於 Java 的開源工具,成千上萬的開發人員在數十萬次安裝中使用它,使其成為最受歡迎的自動化整合工具。這種廣泛使用意味著很容易找到對 Jenkins 的支援和提示,但這並不是它如此廣泛使用的唯一原因。

Jenkins 為 CI 工作流程帶來了許多有趣的範例,包括:

  • 更快的部署。在所有開發人員提交他們的程式碼之後,一次測試和部署構建的日子已經一去不復返了。使用 Jenkins 的自動化 CI/CD 管道,無論何時開發人員提交程式碼,它都會在一天中跨多個週期進行構建和測試。

  • 可擴充套件的主代理架構。在大規模管理分散式構建時,Jenkins 可能是一個不錯的選擇。Jenkins 的主伺服器是排程構建作業並將它們分配給代理(以前是從屬)執行的主伺服器。此模式允許您在一臺或數百臺伺服器上執行 Jenkins 以加快構建速度。

  • 數以千計的外掛:作為一個開源平臺,Jenkins 為其他開發人員構建的持續整合提供了大量外掛。這允許您擴充套件基本功能,而無需在內部編寫或維護大量額外程式碼。

2. 克服常見的 Jenkins 效能問題

隨著時間的推移,構建頻率的增加、並行執行的多個作業以及構建複雜性的增加可能會導致 Jenkins 出現效能問題。您的體驗可能會因您的使用場景而異,但一些常見問題包括:

  • 每次執行時構建似乎都“卡在”特定步驟的“中斷”。

  • 達到單個機器或主節點的記憶體限制。

  • CPU 瓶頸會減慢構建的特定部分。

  • 外掛或指令碼中的錯誤或低效程式碼。

  • 由於這些問題可能是由多種根本原因引起的,因此很難概括解決方案,但 Jenkins 使用者可能想要研究一些事情。以下是一些最通用的方法,您可以提高 Jenkins 構建效能並限制上述問題的頻率。

2.1 避免在管道中使用複雜的 Groovy 指令碼

Jenkins Groovy指令碼控制檯在主節點上執行並直接使用主資源,例如CPU和儲存器。因此,建議您減少管道中 Groovy 指令碼的數量和複雜性,轉而可以直接使用在每個代理上執行的外掛。

在 Jenkins 中要避免的最常見的 Groovy 方法是 JsonSlurper、Jenkins.getInstance 和 HttpRequest。Jenkins在其部落格上有更多關於可擴充套件管道程式碼和要避免的操作的建議。

2.2 在主節點上保持最少的構建

Jenkins 的主節點位於應用程式執行的整個 CI/CD 流程的中心。因此,主節點上的構建數量會顯著影響資源使用。在主節點上保持較少的構建將為代理節點留出足夠的 CPU 和記憶體來安排和觸發作業。

您可以在工作中使用“限制專案可以執行的位置”選項。雖然 Jenkins 仍將在主節點上執行輕量級執行器,但您的重量級執行器將在代理節點上執行。

將主節點視為 Jenkins 的大腦。與代理不同,主節點不能被清除或替換。因此,為確保最佳 CI/CD 功能,請考慮對 Jenkins 進行一些效能調整,並將主節點從不必要的任務中解放出來。這將為您提供足夠的記憶體和 CPU 來有效排程和構建代理上的觸發器。

2.3 不要過渡 Jenkins 主節點外掛安裝

DevOps 專業人員經常跨多個團隊和專案工作,以完成與 CI/CD 相關的任務。如果這是您的情況,請注意不要給單個 Jenkins master 帶來負擔。相反,建立多個主控。多個 master 將確保為 master 分配專案特定的資源,並且您還將避免外掛衝突。

此外,不要設定可能在週期中的任何地方失敗的長時間構建,記住將構建分解為多個較小的作業。

2.4 輕鬆管理代理

在設定 Jenkins 時,正確設定代理很重要。您希望確保在時機成熟時,您可以輕鬆新增新代理或替換現有代理。為此,請考慮為代理建立虛擬機器映象。您也可以考慮在 Kubernetes 或Amazon EKS等可擴充套件叢集中的Docker 容器內執行 Jenkins。

使用具有通用性的代理也是一個好主意;一個代理應該執行多個不同的作業並最大限度地利用資源。

2.5 刪除構建歷史

一段時間後,Jenkins 構建可能會堆積起來,磁碟消耗可能會失控。開發人員經常忽略 Jenkins 的Discard Old Builds選項。設定指標,例如構建數量和保留構建和工件的天數,位於 Jenkins Log Rotation 選單下。

與其讓舊版本累積並消耗檔案系統,開發人員可以啟用Discard Old Builds並在 Jenkins 作業完成後享受自動資源使用清理。您還可以使用 G1 垃圾收集器來代替 Java 8 的預設Parallel GC,因為前者是一種伺服器風格的垃圾收集器,具有較低的 GC 暫停時間。

也可以通過 Jenkins 命令列手動刪除構建,或者使用定期清理舊構建的cron 作業。您可以在此參考文章中找到丟棄舊構建資料的其他選項 https://support.cloudbees.com/hc/en-us/articles/215549798-Deleting-Old-Builds-Best-Strategy-for-Cleanup-and-disk-space-management

2.6 防止並行作業中的資源衝突

並行執行的作業可能需要獨佔訪問埠或資源。這可能會導致衝突、構建失敗並進一步減慢 Jenkins 流水線。例如,如果您並行執行多個構建,則它們在訪問資源時很有可能發生衝突,例如 Postgres 的資料庫埠 5432。

Jenkins 提供Throttle Concurrent Builds外掛來幫助調節 Jenkins 節點上的併發構建數量:

// Throttle a single operation
throttle(['test_1']) {
node() {
sh "sleep 100"
echo "Done"
}
}

2.7 控制堆大小

您想建立以效能為導向且永不會因記憶體洩漏或記憶體不足錯誤而失敗的 CI/CD 管道嗎?注意堆大小。隨著 Jenkins 構建數量的增長,如果不注意預設堆大小可能會導致記憶體不足錯誤。

大多數現代 Java 應用程式在啟動期間都使用最大堆大小配置。為了讓 Jenkins 順利執行,請將最大堆大小屬性降低到最大4 GB。您可以隨時間增加堆大小,具體取決於 Jenkins 構建。

要將堆大小設定為 4 GB:

  • /etc/default/jenkins

  • JAVA_ARGS="-Xmx4096m"

2.8 避免外掛過載

Jenkins 擁有超過一千個可用外掛,為其使用者提供了許多功能來增強他們的 CI/CD 管道。但是,在向管道新增外掛和外部服務時,請牢記效能。將 Jenkins 與外部服務整合通常會減慢 Jenkins UI 並導致不利影響,例如代理丟失或斷開連線。

為了確定外掛是否導致您的構建速度變慢,您可以嘗試在禁用所有或部分外掛的情況下執行構建。逐漸新增每個返回以確定導致瓶頸的原因。找到導致效能問題的外掛(或外掛組合)後,您有幾個選擇:

  • 通過搜尋Jenkins Plugin Index找到替換外掛。

  • 通過檢查changelog來檢視Jenkins 是否添加了對這個特性的原生支援。您可能必須升級 Jenkins 才能獲得最新功能,但這通常是提高效能的好主意。

  • 用自定義指令碼替換外掛,記住這可能會引入新的效能問題。不過,如果您安裝一個複雜的外掛,但只使用一兩個小功能,指令碼可能會更有效。

  • 如果您可以沒有它,請刪除該外掛。有時這是一個值得的權衡。

3.0 跟蹤 Jenkins 效能

當您開始調整 Jenkins 效能時,您可能有興趣新增一個外掛來幫助監控和提高效能。例如,您可以利用Jenkins Monitoring 外掛深入瞭解您的 CI/CD 管道,包括:

  • 錯誤日誌

  • CPU、記憶體和平均系統負載圖表

  • 關於 HTTP 會話和 HTTP 響應時間的報告

  • 構建時間和構建步驟的詳細統計資訊

  • 所有節點的聚合堆直方圖

Jenkins 效能監控工具

這可以幫助您評估效能調整的有效性,並在您繼續改進 Jenkins 安裝時為您提供指導。

4.0 總結

Jenkins 的響應能力問題很常見,尤其是在處理較重的構建時。損壞的 Jenkins CI/CD 管道可能會拖延您的開發團隊並建立不必要的依賴項。本文中討論的技巧應該可以幫助您顯著提高 Jenkins CI/CD 管道的效能。

本文轉載自:「 雲原生技術愛好者社群 」,原文:https://mp.weixin.qq.com/s/u34d-xTZZDs53ZLfqtilxQ,版權歸原作者所有。

推薦閱讀 點選標題可跳轉

《Docker是什麼?》

《Kubernetes是什麼?》

《Kubernetes和Docker到底有啥關係?》

《教你如何快捷的查詢選擇網路倉庫映象tag》

《Docker映象進階:瞭解其背後的技術原理》

《教你如何修改執行中的容器埠對映》

《k8s學習筆記:介紹&上手》

《k8s學習筆記:縮擴容&更新》

《Docker 基礎用法和命令幫助》

《在K8S上搭建Redis叢集》

《灰度部署、滾動部署、藍綠部署》

《PM2實踐指南》

《Docker垃圾清理》

《Kubernetes(k8s)底層網路原理刨析》

《容器環境下Node.js的記憶體管理》

《MySQL 快速建立千萬級測試資料》

《Linux 與 Unix 到底有什麼不同?》

《淺談幾種常見 RAID 的異同》

《Git 筆記-程式設計師都要掌握的 Git》

《老司機必須懂的MySQL規範》

《Docker中Image、Container與Volume的遷移》

《漫畫|如何用Kubernetes搞定CICD》

《寫給前端的Docker實戰教程》

《Linux 作業系統知識地圖2.0,我看行》

《16個概念帶你入門 Kubernetes》

《程式設計師因接外包坐牢456天,長文敘述心酸真實經歷》

《IT 行業老鳥,有話對你說》

《HTTPS 為什麼是安全的? 說一下他的底層實現原理?

免責宣告:本文內容來源於網路,所載內容僅供參考。轉載僅為學習和交流之目的,如無意中侵犯您的合法權益,請及時聯絡Docker中文社群!