1. 程式人生 > >解決jenkins產生的日誌過大以及一些衍生問題

解決jenkins產生的日誌過大以及一些衍生問題

jenkins使用一段時間後,會導致出現比較大的日誌問題,經常佔滿硬碟空間(因為我們使用的硬碟大小20G,無額外儲存要求)。在硬碟空間佔滿之後,會導致一些基本的命令都無法使用,譬如tab都不能出結果。 其中顯示的日誌,就例如下面的樣例:
        question:      [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
        question:      [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
        question:      [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
        question:      [
[email protected]
type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [
[email protected]
type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [
[email protected]
type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
  而且我們將已經定位到的檔案刪除掉,仍然不能釋放空間,經過檢視可以深層次發現其中的問題。 未釋放磁碟空間原因 在Linux或者Unix系統中,通過rm或者檔案管理器刪除檔案將會從檔案系統的資料夾結構上解除連結(unlink).然而假設檔案是被開啟的(有一個程序正在使用),那麼程序將仍然能夠讀取該檔案,磁碟空間也一直被佔用。而我刪除的是jenkins的日誌檔案,如果jenkins服務沒有停止,此時刪除該檔案並不會起到什麼作用。 刪除的時候檔案應該正在被使用 當linux開啟一個檔案的時候,Linux核心會為每個程序在/proc/ 『/proc/nnnn/fd/資料夾(nnnn為pid)』建立一個以其pid為名的資料夾用來儲存程序的相關資訊,而其子資料夾fd儲存的是該程序開啟的全部檔案的fd(fd:file descriptor)。 kill程序是通過截斷proc檔案系統中的檔案能夠強制要求系統回收分配給正在使用的的檔案,這是一項高階技術,僅到管理員確定不會對執行中的程序造成影響時使用。應用程式對這樣的方式支援的並不好,當一個正在使用的檔案被截斷可能會引發不可預知的問題,所以最終還是採用停止jenkins應用來解決該問題。

    當一個檔案正在被一個程序使用時,使用者刪除此檔案,檔案只會從目錄結構中刪除,但並沒有從磁碟刪除。當使用這個檔案的程序結束後,檔案才會真正的從磁碟刪除,釋放佔有的空間。

    我們發現剩餘磁碟空間比較少時,回去刪除一些大的臨時檔案或者log檔案,如果刪除之後會發現磁碟空間並未減少,那麼可以通過“lsof”命令去檢視正在使用該檔案的程序,然後再重啟該程序或者服務。 一般情況下,jenkins的部署常用幾種方式:
  1. 通過系統服務安裝並啟動:service jenkins start/stop/restart,此時就可以通過命令來停止;
  2. 將war包部署至tomcat中,此時stop tomcat伺服器就可以了。
而jenkins的日誌問題經過google一番,找出相應的幾個解決方法: 先考慮在jenkins上安裝兩個外掛:

This plugin monitors the size of the output file of a build and aborts the build if the log file gets too big.

Or, if this has also an impact on the runtime, the Build-timeout Plugin:

This plugin allows you to automatically abort a build if it's taking too long. Once the timeout is reached, Jenkins behaves as if an invisible hand has clicked the "abort build" button.

在jenkins中也已經意識到了該問題,並有了初步的解決方案: 根據朱迪的調研,考試使用下面的方式來解決此問題:
 
This seems to be due to DNS multicast as explained here: https://issues.jenkins-ci.org/browse/JENKINS-25369
Workaround: add -Dhudson.DNSMultiCast.disabled=true to JAVA_ARGS.
PS: I'm answering my own question here on Stack Overflow because I couldn't find the answer on Google easily, and it will be useful to other people running Jenkins.
   日誌中出現過多的DNS相關錯誤。 此外,還有一些其他需要值得注意的點,例如在指令碼中如果涉及到啟動程序的話,需要加入BUILD_ID,否則該進行啟動後就會被kill掉。 如果不設定BUILD_ID,則jenkins在結束自己的指令碼執行時會將建立的所有subprocess kill掉,BUILD_ID是Jenkins的一個環境變數,如果不隨便改成一個值,那麼由於startup.sh是fork一個程序執行的,Jenkins執行完所有指令碼就會退出,帶著subprocess一起死掉,具體的解釋原因詳見: