1. Jenkins Master Configuration
插件數量 插件會導致構建(因為hook)和UI(插件會添加界面元素到UI中)加載時的性能問題,不要添加過多的插件,一定要充分評估插件后再安裝。
2.Job數量
當單個Master job數量達到1000+時 UI訪問會開始有延遲 這時可以選擇增加Jenkins Master數量來提升瓶頸,但是增加Jenkins Master等於拆分jenkins任務,目前還沒有多Master Jenkins集群,近期未來預計也不會有。所以在不定制Jenkins的情況下,唯一能夠實現負載在Master之間共享的,只能是搭建多個Master,分別支持不同的Job。
3.禁止在Master上運行Job
Master上不應該運行Job,或者只能運行對Jenkins管理至關重要的內部輕量級任務(Jenkins備份、Job清理等),絕對不能運行業務Job。
減少在Master上輪詢SCM 針對Git或者Perforce的SCM輪詢需要為每個Job的每次輪詢運行CLI程序。如果想要可靠的輪詢,則應該運行在Master上,不建議在Slave上輪詢,因為Slave是不可靠的。 建議使用push hooks代替輪詢。
Git可以在大多情況下使用Gerrit Trigger的“Refupdate”事件來代替SCM輪詢,針對Perforce,可以將輪詢時間間隔設置的長一些。
至於Subversion則使用的是SVNkit而不是CLI程序,所以其不受影響。
4.磁盤IO性能
- 為Job配置(啟動時)和Build記錄(延遲加載)使用更快的磁盤,Master采用SSD會很有幫助,分離配置、BUild記錄、構件存儲。可插拔的構件轉移和存儲會值得研究(JENKINS-17236)。
- 使用外部API/UI作為Jenkins前端。
- Jenkins並不擅長UI性能,UI插件會導致UI性能變的更糟。外部的UI面板或前端系統可以作為替代方案,引發性能問題的插件:Dashboard view plugin 會引發延遲加載問題 Nested View plugin會引發多次針對每個Job的權限重復認證問題,使用正則表達式過濾Job會變的更糟。可以嘗試使用明確的Job list,而不是正則表達式。可以使用 Cloudbees Folders Plugin 代替,這個插件可能有效,但是需要評估。
- HTTP緩存 使用快速的HTTP代理以緩存靜態數據可以幫助提升性能,但是需要進一步平塗
使用Nginx除了代理端口轉發之外,還可以緩存靜態文件,比如圖片、CSS等,即動靜分離,是Web應用的常見方法 Servlet容器。
5.Jenkins Slave Configuration
5.1 Slave數量
Jenkins開發團隊與一個目標叫“X1K initiative”,即保證Jenkins Master能支持所有Slave共1000個執行器的平滑運行,到目前為止,這依然是一個挑戰。有時候當Slave在250台左右出現大量Slave連接在構建過程中中斷的情況。有證據顯示當Slave過百時,Jenkins會出現Slave連接丟失的情況。因為在Jenkins core 1.521和SSH Slave Plugin 0.27中針對Jenkins remoting做的線程使用改進不應該出現這樣的問題,但是並沒有得到證實。
5.2 單個Slave的執行器數量
超過Slave容量的情況下,增加執行器數量會因為崩潰、IO阻塞、RAM交換導致整體的吞吐量下降,合理配置 RAM, CPU cores and build 類型。關於RAM的配置,Slave的maximum memory setting配置需要能夠支持最大了的Build。CPU應該足夠使用,不會達到100%使用率。考慮IO時,IO會釋放一些CPU時間,針對單線程的Build,每個CPU核心配置應少於1個執行器。考慮到IOPS限制,為了避免磁盤IO成為瓶頸,一般情況下,如果15分鍾內,平均負載超過了CPU核心數量,則執行器數量應該降低。建議,每個Slave配置1個執行器以便實現隔離。基於雲的Slave可以很方便的實現隔離,如果是基於專用硬件,可以通過輕量級容器實現同樣的隔離。
6.workspace清理
定時清理Workspace 設置構建過期時間 清理老的構建任務 釋放磁盤空間,job有時單個任務空間達到幾個G也是導致jenkins加載緩慢
7. JVM性能優化
JENKINS_JAVA_OPTIONS=”-Djava.awt.headless=true -Xms10240m -Xmx10240m -XX:MaxNewSize=1024m -XX:MaxPermSize=1024m”
- -Xmx:表示java虛擬機堆區內存可被分配的最大上限,通常為操作系統可用內存的1/4大小
- -Xms:初始堆大小,表示java虛擬機堆區內存初始內存分配的大小,通常為操作系統可用內存的1/64大小即可,但仍需按照實際情況進行分配
開發過程中,通常會將-Xms 與-Xmx兩個參數的配置相同的值,其目的是為了能夠在java垃圾回收機制清理完堆區后不需要重新分隔計算堆區的大小而浪費資源。
- -XX:newSize:表示新生代初始內存的大小,應該小於-Xms的值;
- -Xmn:至於這個參數則是對 -XX:newSize、-XX:MaxnewSize兩個參數的同時配置,也就是說如果通過-Xmn來配置新生代的內存大小,那么-XX:newSize = -XX:MaxnewSize = -Xmn,雖然會很方便,但需要注意的是這個參數是在JDK1.4版本以后才使用的
- -XX:PermSize:表示非堆區初始內存分配大小(方法區)
- -XX:MaxPermSize:表示對非堆區分配的內存的最大上限(方法區)
最大堆內存與最大非堆內存的和絕對不能夠超出操作系統的可用內存
-Xms: 使用的最小堆內存大小
-Xmx: 使用的最大堆內存大小
-XX:PermSize: 內存的永久保存區域大小
-XX:MaxPermSize: 最大內存的永久保存區域大小
這幾個參數也不是配置越大越好,具體要根據所在機器實際內存和使用大小配置。
-
設置全局屬性
適當設置全局屬性,可以避免在 Job 中重復寫一些固定值,例如輸出日志地址、接口請求地址等等,而且當固定值需要修改時,只需要修改一次即可,不用去每個 Job 里面修改,方便維護 -
構建超時時間
有些 Job 在執行構建時,由於某些原因導致構建掛起,耗時比較長,而這些長時間掛起的 Job 會導致 Jenkins 內存占用比較大,性能下降,嚴重的會直接導致 Jenkins 掛掉。所以,我們需要設置構建超時時間來預防這種事情發生,一旦超過一定的時間,要讓 Job 自動停止掉