jenkins使用一段時間后,會導致出現比較大的日志問題,經常占滿硬盤空間(因為我們使用的硬盤大小20G,無額外存儲要求)。在硬盤空間占滿之后,會導致一些基本的命令都無法使用,譬如tab都不能出結果。
其中顯示的日志,就例如下面的樣例:
question: [DNSQuestion@1138295053 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@815573059 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@41696207 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@2028905592 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@1941181185 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@641688452 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@1165924047 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@1220425596 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@465635697 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@1186949838 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@2009482296 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@1316653163 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@1575193172 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@1622635068 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ] question: [DNSQuestion@630525334 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的部署常用幾種方式:
- 通過系統服務安裝並啟動:service jenkins start/stop/restart,此時就可以通過命令來停止;
- 將war包部署至tomcat中,此時stop tomcat服務器就可以了。
而jenkins的日志問題經過google一番,找出相應的幾個解決方法:
先考慮在jenkins上安裝兩個插件:
|
You can use the Logfilesizechecker Plugin:
Or, if this has also an impact on the runtime, the Build-timeout Plugin:
|
在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一起死掉,具體的解釋原因詳見: