1. 程式人生 > >JIRA應用的記憶體引數設定不當+容器沒有對資源進行限制導致服務掛掉的例子

JIRA應用的記憶體引數設定不當+容器沒有對資源進行限制導致服務掛掉的例子

背景:
應用的部署結構是這樣的:使用rancher管理的Docker叢集,有三臺物理主機,二十多個Docker容器,
提供的功能是問題跟蹤(JIRA),文件管理(Confluence),程式碼託管(svn,gitlab),持續整合(jenkins,gitlab-ci + Docker),程式碼質量管理(Sonar),構件管理(nexus3)和測試管理(TestLink)的功能.服務於1400多個研發人員

前端使用Apache來對後端的服務進行反向代理,同時Apache集成了CAS和LDAP 提供了單點登入的功能

某天下午,使用者反饋,應用訪問的速度非常的慢,登入的請求也無法響應了.

到Apache所在的主機上看資源的佔用,,發現CPU佔用率超過500%,apache沒有足夠的CPU資源來處理請求

通過在主機上ps這個CPU超過500%的程序,發現是一個java的程序,對應的是JIRA的容器

主機上顯示的程序號,和容器裡邊的程序號是不一樣的

在容器裡,JIRA對應的java程序是程序號為1的程序

進入JIRA容器

dump出來這個程序的所有的執行緒棧

jstack 1 > jirastack.log

檢視這個程序中的佔cpu最高的執行緒

top -Hp 1

得到的結果如下:

可以看到,有8個執行緒的CPU佔用都超過了70左右,合計起來是 500%多

前邊的 49,53之類的是和執行緒棧裡邊的執行緒的nxID對應的,只不過,nxID是用十六進位制來表示的

我們把這些十進位制的數字也變成十六進位制

從dump出來的執行緒棧裡邊找到了對應的執行緒:

從執行緒棧裡邊搜尋 nid=0x31,搜到了以下的執行緒

我們可以看到,這些都是垃圾回收的執行緒,垃圾回收的執行緒佔據了所有的CPU的時間

檢視JIRA的引數設定,發現了記憶體的設定較小 -Xms1024m -XmX2048m,使用的垃圾收集器是ParallelGC,因為主機的CPU有8個核心,所以就預設啟動了8個垃圾收集器的執行緒

系統的使用者大概有2k人,都是開發和測試人員來使用,對比另一個應用 confluence的記憶體配置(6G的堆大小,G1垃圾收集器),JIRA的堆的配置是有點小了,所以把JIRA的堆記憶體設定為4G(主機所在的記憶體還有很多沒有使用)然後針對增大的這個堆,啟用G1垃圾收集器,然後列印了垃圾收集的日誌資訊到一個日誌檔案裡邊

配置如下:

JVM_MINIMUM_MEMORY 和 JVM_MAXIMUM_MEMORY的值都是4096m

然後,為了防止某個容器佔用的資源過多,影響其他的容器(就是開頭的時候我們遇到的問題,JIRA佔用的CPU過多,導致了apache無法響應請求,其他的應用都無法訪問了),所以,我們在rancher上對容器的資源做了一些限制