『壹』 查看linuxgc日誌,求助,GC和GC有什麼區別啊GC和GC有什麼區
java雖然是自動回收內存,但是應用程序,尤其伺服器程序最好根據業務情況指明內存分配限制。否則可能導致應用程序宕掉。 舉例說明含義: -Xms128m 表示JVM Heap(堆內存)最小尺寸128MB,初始分配 -Xmx512m 表示JVM Heap(堆內存)最大允許的尺寸256
『貳』 Tomcat假死排查
最近在重啟生產環境項目後偶爾會出現這個情況:瀏覽器訪問頁面,無報錯一直處於載入狀態,伺服器上tomcat日誌沒有訪問記錄輸出,也沒有異常日誌輸出,再次重啟tomcat後才正常運行。
後續經過網上一番查找才得知這是tomcat假死的情況,由於當時情況緊急沒有時間排查原因,只忙著重啟解決(小型項目,沒有做集群),這里就記錄一下排查思路,防止下次遇到後再這樣暴力解決。
1.項目雖然沒有做集群,但是有nginx做反向代理,所以第一步應該是查看nginx上的access.log日誌。倘若有訪問記錄日誌列印,則表示前端到nginx無問題。
2.接著排查nginx到tomcat的情況。
查看tomcat的訪問日誌localhost_acess.log有沒有本次請求記錄,沒有記錄先懷疑是否網路有問題。從該台nginx ping 了一下tomcat server ,正常,沒有發現問題。既然網路貌似沒有問題,開始懷疑是tomcat本身的問題,在tomcat本機直接curl 調用該條請求,發現仍然沒有響應。到此基本可以斷定網路沒有問題,tomcat 本身出現了假死的情況。
基於tomcat 假死的情況,開始分析有可能的原因。造成tomcat假死有可能的情況大概有以下幾種:
1.內存溢出
分析當時的gc.log 是否有內存溢出的情況,或者直接 grep OutOfMemoryException catalina.sh 查看是否有內存溢出異常。
2.jvm GC 時間過長,導致應用暫停
查看gc.log回收時間,以下為例子:
最近的一次full gc 顯示,也不應該會暫停幾分鍾的情況,這種假死可能可以排除。
3.load 太高,已經超出服務的極限
當時top一下linux
load 並不是高,這種假死可能可以排除。
4.應用程序出現死鎖,需要使用jstack進行線程分析
5.大量tcp 連接 CLOSE_WAIT
使用命令 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
6.tomcat長連接數超過最大連接數
tomcat默認最大連接數(線程數)200個,默認每一個連接的生命周期2小時(7200秒),tomcat使用http 1.1協議,而http1.1默認是長連接。tomcat接受處理完請求後,socket沒有主動關閉,因此如果在2小時內,請求數超過200個,伺服器就會出現上述假死現象。解決辦法:
1.修改tomcat server.xml配置文件,增大最大連接數
2.修改linux的TCP超時時間(socket生命周期)限制
『叄』 記一次服務Full GC背後的內存泄漏問題,真是匪夷所思
最近所負責的服務略頻繁地收到4xx告警
1、查業務日誌,沒發現相關錯誤的日誌
2、查nginx access log,發現返回的狀態碼都是499,從request_uri查了一遍發現不是集中在某一個請求上,說明應該不是某個介面的問題了,有可能進程層面問題了。
通過對upstream_addr 分類,可以看到問題基本都是集中在 某一台這台機器上
3、網上資料了解到,499 是 nginx 擴展的 4xx 錯誤,代表客戶端請求還未返回時,客戶端主動斷開連接。原因有幾種,不過大部分原因都說到有可能伺服器upstream處理過慢,導致用戶提前關閉連接。那就先往這個方向排查,登錄機器查看實際的access.log
發現upstream response都是10s以上。這就證明了上游伺服器處理10秒還沒有響應,因此nginx提前關閉鏈接,返回499
4、為什麼進程響應如此慢,10秒太不正常了。考慮到那段時間就只有一台機器有問題,而且是進程層面的問題,首先想到的是GC,於是再次登錄到機器上查看gc log。發現有Full GC,時間點和告警的時間也吻合。 驚呆的是,這次FullGC耗時長達19.07秒,由於我們的服務使用的是jdk8默認的ParallelGC,FullGC期間,整個應用Stop The World的。這是非常恐怖的一件事
由此看來,4xx告警的初步原因已經定位到,就是FullGC導致的。
那麼究竟為什麼會發生FullGC呢?需要深入分析一下。
藉助服務治理平台的JVM監控觀察了幾天。期間不同機器不同時間也發生了幾次FullGC。從監控發現,基本每台機器隔兩天就會發生一次FullGC,每次FullGC後年老代回收的垃圾不算多,使用比例還是挺高的。
為什麼年老代空間佔用這么多?
繼續分析上面那條full gc log,
1、發生full gc時,年老代內存已經佔用了99.98%了(1048397/1048576)。看起來因為年老代滿了而觸發的FullGC了。
2、full gc回收了年老代大約302M的垃圾,回收後年老代佔用70.4%(738282/1048576)。這佔用率還是比較高的。
1、首先jmap簡單列印一下所有對象的信息。發現有ClassPathList和ClassClassPath兩個類的對象數量高達1000多萬,並且這兩個數量是一樣的。彷彿嗅到了內存泄漏的味道。
2、只依靠對象統計信息,不足以定位問題,需要使用完整HeapDump,通過MAT進一步分析
jmap把完整堆heapDump下來
隔一段時間後,繼續jmap,這次只取存活對象的mp(實際效果是先執行一次FULL GC)
可以看到,經過Full GC後,ClassPathList對象沒有被回收,數量反而繼續增加。到這里,基本可以確定,ClassPathList是存在泄漏了。
那麼,ClassPathList究竟被誰引用著,導致回收不掉呢?
通過MAT的OQL過濾出老生代的ClassPathList對象,從對象的關聯關繫上繼續深入分析。
首先需要知道老生代的地址區間,可以使用vjtools
通過vjmap的address命令,快速列印各代地址。
可以得知,oldGen的下界是0x80000000,上界是0xc0000000(注意OQL中使用時要把數值前的那串0去掉)。
執行OQL只查詢年老代中的ClassPathList對象:執行OQL只查詢年老代中的ClassPathList對象:
抽取其中一個對象分析,可以發現這個ClassPathList對象被一連串不同ClassPathList對象的next屬性引用著。看起來是個鏈表的結構
再看看GCRoot,發現是被AppClassLoader也就是我們的應用類載入器引用著。除非這個載入器卸載了,否則ClassPathList對象是不會被GC掉了。
分析到這里,似乎離真相越來越近了。到底這個ClassPathList在項目中哪裡使用到了?
通過前面的分析知道了ClassPathList的整體引用關系鏈:
AppClassLoader -> ClassPool類的defaultPool欄位 -> ClassPoolTail類的source欄位 -> ClassPathList類的pathList
可以看到,ClassPathList有兩個屬性,一個是next,結合之前MAT的分析,ClassPathList的確就是一個鏈表的結構。隨著時間的增長,ClassPathList不斷新增,鏈表也隨之變得越來越大,最後內存佔用逐漸上升。
另一個path欄位屬於ClassPath類型,ClassPath是個介面,查看它的實現類,發現一個似曾相識的名稱ClassClassPath,之前分析對象統計信息時,還有一個類的對象數量是和ClassPathList一樣的,正是這個ClassClassPath。每新增一個ClassPathList,都會伴隨著新增對應的ClassPath對象,這也解釋了為什麼兩者數量是一致的了。
通過注釋知道,這個ClassClassPath的作用大概就是,利用一個叫ClassPool的對象,可以調用其insertClassPath方法來新增一個ClassClassPath對象,insertClassPath方法內部通過頭插法將ClassClassPath添加到ClassPathList鏈表,從而形成一個search-path,然後通過這個search-path能夠獲取到某一個Class類的信息。
於是嘗試著搜了一下,看看項目中有沒有調用到insertClassPath方法的地方。意外發現一個類,
這不就是我們項目用來列印方法入參、執行耗時、上報metrics的@AutoLog的實現類嗎。
可以看到getParams方法中調用了insertClassPath,註解@AutoLog的printParams默認為true,也就是每次調用都需要列印方法入參,每次列印前都要調用getParams先獲取參數名稱。因此每次都會insertClassPath,從而導致ClassPathList鏈表越來越大。
至此,內存泄漏的元兇已經找到。解決方法也就簡單了。
因為目標只是想得到方法的參數名稱,通過JoinPoint其實能直接獲取到,因此可以改成JoinPoint獲取的方式。
為了進行對比,分別在修改前後各進行一次壓測。壓測JVM參數大致與線上一致,為了盡快看到效果,只是調小了heap的大小。-Xms200m -Xmx200m
ClassPathList數量不斷增長
年老代每次能回收的垃圾越來越少,每次回收過後的剩餘空間也越來越小。最終整個年老代被撐滿
雖然還沒觸發OOM,但是CPU負載飆高,從基本都在處於頻繁的FULLGC狀態
ClassPathList已經被消滅掉了
FullGC也趨於規律化了。每次回收的垃圾大致都相同
第一種方式是在啟動參數增加 -XX:+PrintHeapAtGC,每次GC都列印地址
第二種方式是使用vjmap的命令,在-old, -sur, -address 中,都會列印出該區間的地址
第三種方式,使用vjmap的address命令,快速列印各代地址,不會造成過長時間停頓。
附: 我們服務的JVM參數
『肆』 幾種常見GC簡介
在springboot-admin當中,大概會有以下幾種類型的gc出現,本文我們看看他們分別是什麼意思。
本文使用的垃圾收集器是jdk1.8的PS+PO。
顧名思義,就是內存分配失敗導致的GC,常見於年輕代當中。
使用JNI臨界區的方式操作數組或者字元串時,為了防止GC過程中jarray或者jstring發生位移,而導致數組指針失效,需要保持它們在JVM Heap中的地址在JNI Critical過程中保持不變。於是JVM實現了GC_locker,用於JNI Critical內阻止其他GC的發生。
當GCLocker被激活且需要發生GC的時候(這里是否需要GC是各種GC發生時,調用GCLocker::check_active_before_gc()函數check並設置_needs_gc = true的),就會阻塞其他線程進入JNI臨界區;並且在最後一個位於JNI臨界區的線程退出臨界區時,發起一次CGCause為_gc_locker的GC。這里解釋了GCLocker Initiated GC發生的原委。
在JVM中的垃圾收集器中的Ergonomics就是負責自動的調解gc暫停時間和吞吐量之間的平衡,使你的虛擬機性能更好的一種做法。
簡單說就是內存在進行分配的時候,會通過一些演算法,預估是否會出現無法分配的問題。如果符合無法分配預估值,會提前進行一次gc。
這個gc主要發生的條件是元空間,也就是Metadata的參數設置問題。
通常根據我們學習的JVM只是,元空間使用的是本地內存,所以應該與當前伺服器的最大內存有關。
但實際不是這樣的,在jdk1.8中,如果不設置元空間的大小,會有一個默認值是 21M 。
所以需要我們啟動的時候指定一個元空間大小:
GC日誌如下所示:
『伍』 如何開啟Tomcat的日誌記錄功能
Windows中的tomcat開啟gc日誌的方法:在catlinna.bat中添加set CATALINA_OPTS=-XX:ParallelGCThreads=4 -XX:+PrintGCDetails -Xloggc:D:/work/apache-tomcat-7.0.37-windows-x64/apache-tomcat-7.0.37/logs/tomcat_gc.log,gc日誌就會列印到我們指定的日誌文件中。 它的格式應該是這樣:
Young gc 86.188: [GC [PSYoungGen: 32896K->880K(33024K)] 98532K->66588K(99264K), 0.0041792 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
『陸』 弱弱的問一句 jvm full gc到底是啥意思
JVM 內置的通用垃圾回收原則,堆內存劃分為 Eden、Survivor 和 Tenured/Old 空間。GC一共分三種:MinorGC,Major GC v和Full GC。Full GC是清理整個堆空間—包括年輕代和永久代。有時候系統會頻繁的FullGC,這時候需要去伺服器查一下原因。
當編輯並運行一個Java程序時,需要同時涉及到這四種方面。使用文字編輯軟體(例如記事本、寫字板、UltraEdit等)或集成開發環境(Eclipse、MyEclipse等)在Java源文件中定義不同的類 ,通過調用類(這些類實現了Java API)中的方法來訪問資源系統,把源文件編譯生成一種二進制中間碼,存儲在class文件中,然後再通過運行與操作系統平台環境相對應的Java虛擬機來運行class文件,執行編譯產生的位元組碼,調用class文件中實現的方法來滿足程序的Java API調用。
(6)伺服器怎麼查看gc日誌擴展閱讀
觸發Full GC執行的情況有如下四種。舊生代空間不足
1.舊生代空間只有在新生代對象轉入及創建為大對象、大數組時才會出現不足的現象,當執行Full GC後空間仍然不足,則拋出如下錯誤:
java.lang.OutOfMemoryError: Java heap space
為避免以上兩種狀況引起的FullGC,調優時應盡量做到讓對象在Minor GC階段被回收、讓對象在新生代多存活一段時間及不要創建過大的對象及數組。
2. Permanet Generation空間滿
PermanetGeneration中存放的為一些class的信息等,當系統中要載入的類、反射的類和調用的方法較多時,Permanet Generation可能會被占滿,在未配置為採用CMS GC的情況下會執行Full GC。如果經過Full GC仍然回收不了,那麼JVM會拋出如下錯誤信息:
java.lang.OutOfMemoryError: PermGen space
為避免Perm Gen占滿造成Full GC現象,可採用的方法為增大Perm Gen空間或轉為使用CMS GC。
3. CMS GC時出現promotion failed和concurrent mode failure
對於採用CMS進行舊生代GC的程序而言,尤其要注意GC日誌中是否有promotion failed和concurrent mode failure兩種狀況,當這兩種狀況出現時可能會觸發Full GC。
promotionfailed是在進行Minor GC時,survivor space放不下、對象只能放入舊生代,而此時舊生代也放不下造成的;concurrent mode failure是在執行CMS GC的過程中同時有對象要放入舊生代,而此時舊生代空間不足造成的。
應對措施為:增大survivorspace、舊生代空間或調低觸發並發GC的比率,但在JDK 5.0+、6.0+的版本中有可能會由於JDK的bug29導致CMS在remark完畢後很久才觸發sweeping動作。對於這種狀況,可通過設置-XX:CMSMaxAbortablePrecleanTime=5(單位為ms)來避免。
4. 統計得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間
這是一個較為復雜的觸發情況,Hotspot為了避免由於新生代對象晉升到舊生代導致舊生代空間不足的現象,在進行Minor GC時,做了一個判斷,如果之前統計所得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間,那麼就直接觸發Full GC。
例如程序第一次觸發MinorGC後,有6MB的對象晉升到舊生代,那麼當下一次Minor GC發生時,首先檢查舊生代的剩餘空間是否大於6MB,如果小於6MB,則執行Full GC。
當新生代採用PSGC時,方式稍有不同,PS GC是在Minor GC後也會檢查,例如上面的例子中第一次Minor GC後,PS GC會檢查此時舊生代的剩餘空間是否大於6MB,如小於,則觸發對舊生代的回收。
除了以上4種狀況外,對於使用RMI來進行RPC或管理的Sun JDK應用而言,默認情況下會一小時執行一次Full GC。可通過在啟動時通過- java-Dsun.rmi.dgc.client.gcInterval=3600000來設置Full GC執行的間隔時間或通過-XX:+ DisableExplicitGC來禁止RMI調用System.gc。
參考資料來源:網路-JAVA
『柒』 配置Elasticsearch
Elasticsearch船隻具有良好的默認值,並且只需要很少的配置。可以在運行的集群上使用集群更新設置API更改大多數設置。
配置文件應該包含特定於節點的設置(例如node.name和路徑),或者節點為了能夠加入集群而需要的設置,例如 cluster.name 和 network.host 。
Elasticsearch有三個配置文件:
這些文件位於config目錄中,其默認位置取決於安裝是來自存檔分發版(tar.gz或zip)還是包分發版(Debian或RPM包)。
對於存檔發行版,config目錄位置默認為 $ES_HOME/config 。配置目錄的位置可以通過 ES_PATH_CONF 環境變數改變,如下所示:
或者,您可以通過命令行或shell配置文件導出ES_PATH_CONF環境變數。
對於包分發,配置目錄位置默認為 /etc/elasticsearch 。配置目錄的位置也可以通過 ES_PATH_CONF 環境變數更改,但是請注意,僅在shell中設置是不夠的。相反,這個變數來源於 /etc/default/elasticsearch (用於Debian包)和 /etc/sysconfig/elasticsearch (用於RPM包)。您需要相應地在其中一個文件中編輯 ES_PATH_CONF=/etc/elasticsearch 條目,以更改配置目錄的位置。
配置格式為YAML。下面是更改數據和日誌目錄路徑的示例:
設置也可以扁平化如下:
在YAML中,你可以將非標量值格式化為序列:
雖然不太常見,但你也可以將非標量值格式化為數組:
使用${…}符號將被替換為環境變數的值。例如:
環境變數的值必須是簡單字元串。使用逗號分隔的字元串來提供Elasticsearch將解析為列表的值。例如,Elasticsearch將以下字元串分割為 ${HOSTNAME} 環境變數的值列表
集群和節點設置可以根據配置方式進行分類:
您可以使用 集群更新設置API 在運行的集群上配置和更新動態設置。您還可以使用 elasticsearch.yml 在未啟動或關閉的節點上本地配置動態設置。
使用集群更新設置API進行的更新可以是持久的(跨集群重啟應用),也可以是短暫的(在集群重啟後重置)。您還可以通過使用API為臨時或持久設置賦值為空來重置它們。
如果您使用多個方法配置相同的設置,Elasticsearch將按照以下優先順序應用這些設置:
例如,您可以應用瞬變設置來覆蓋持久設置或 elasticsearch.yml 設置。然而,對 elasticsearch.yml 的更改,不會覆蓋已定義的瞬態或持久設置。
最好使用集群更新設置API設置動態的集群范圍設置,並使用 elasticsearch.yml 僅用於本地配置。使用集群更新設置API可以確保所有節點上的設置是相同的。如果您不小心在 elasticsearch.yml 中配置了不同的設置。在不同的節點上,很難注意到差異。
靜態設置只能在未啟動或關閉的節點上使用 elasticsearch.yml 進行配置。
必須在集群中的每個相關節點上設置靜態設置
Elasticsearch開始時只需要很少的配置,但是在生產環境中使用集群之前,有很多方面需要考慮:
Elasticsearch將創建索引的數據寫入索引,將數據流寫入數據目錄。Elasticsearch將自己的應用程序日誌(其中包含關於集群運行狀況和操作的信息)寫入日誌目錄
對於macOS .tar.gz、Linux .tar.gz和Windows .zip安裝,數據和日誌默認是 $ES_HOME 的子目錄。但是,在升級過程中, $ES_HOME 中的文件有被刪除的風險
In proction, we strongly recommend you set the path.data and path.logs in elasticsearch.yml to locations outside of $ES_HOME . Docker , Debian , RPM , macOS Homebrew , and Windows .msi installations write data and log to locations outside of $ES_HOME by default.
To avoid errors, only Elasticsearch should open files in the path.data directory. Exclude the path.data directory from other services that may open and lock its files, such as antivirus or backup programs.
Supported path.data and path.logs values vary by platform
只有當一個節點與集群中的所有其他節點共享 cluster.name 時,該節點才能加入集群。默認名稱是 elasticsearch ,但是您應該將其更改為描述集群用途的適當名稱。
不要在不同的環境中重用相同的集群名稱。否則,節點可能會加入錯誤的集群
Elasticsearch使用 node.name 作為Elasticsearch特定實例的人類可讀標識符。這個名稱包含在許多api的響應中。當Elasticsearch啟動時,節點名默認為機器的主機名,但是可以在 elasticsearch.yml 中顯式配置
預設情況下,Elasticsearch只綁定到 127.0.0.1 和 [::1] 等環回地址。這對於在單個伺服器上運行一個或多個節點的集群進行開發和測試已經足夠了,但是 彈性生產集群 必須包含其他伺服器上的節點。有許多 網路設置 ,但通常你只需要配置 network.host :
當你為 network.host 提供值時。Elasticsearch假定您正在從開發模式轉向生產模式,並將一些系統啟動檢查從警告升級到異常。看看 開發和生產模式 之間的區別。
在投入生產之前,配置兩個重要的發現和集群形成設置,以便集群中的節點能夠相互發現並選擇一個主節點。
Elasticsearch可以開箱即用,無需任何網路配置,它將綁定到可用的環回地址,並掃描本地埠 9300 到 9305 ,以便與運行在同一伺服器上的其他節點連接。這種行為提供了一種無需進行任何配置的自動集群體驗。
當您希望與其他主機上的節點形成集群時,使用 靜態 discovery.seed_hosts 設置. This setting provides a list of other nodes in the cluster that are master-eligible and likely to be live and contactable to seed the discovery process .
此設置接受集群中所有符合主節點的地址的YAML序列或數組。每個地址可以是一個IP地址,也可以是通過DNS解析為一個或多個IP地址的主機名。
當您第一次啟動Elasticsearch集群時, 集群引導 步驟將確定在第一次選舉中計票的符合主資格的節點集。在 開發模式 下,如果沒有配置發現設置,這個步驟將由節點自己自動執行。
因為自動引導 本身就不安全 ,,所以在生產模式下啟動新集群時,必須顯式列出符合主資格的節點,這些節點的投票應該在第一次選舉中計算。您可以使用集群設置此列表。 initial_master_nodes 設置。
在集群第一次成功形成之後,刪除每個節點配置中的 Initial_master_nodes 設置。在重新啟動集群或向現有集群添加新節點時,不要使用此設置。
通過節點的 node.name 標識初始主節點, 該節點默認為主節點的主機名。請確保 cluster.initial_master_nodes 值 與 node.name 完全匹配如果您使用完全限定的域名(FQDN),例如master-node-a.example.com作為您的節點名,那麼您必須在此列表中使用FQDN。相反,如果node.name是沒有任何尾隨限定符的裸主機名,您也必須省cluster.initial_master_nodes中的尾隨限定符如果您使用完全限定的域名(FQDN),例如 master-node-a.example.com 作為您的節點名, 那麼您必須在此列表中使用FQDN。相反,如果f node.name 是沒有任何尾隨限定符的裸主機名,您也必須省略 cluster.initial_master_nodes 中的尾隨限定符。
請參見 bootstrapping a cluster 以及 發現和集群形成設置 .
默認情況下,Elasticsearch會根據節點的 角色 和總內存自動設置JVM堆大小。對於大多數生產環境,我們建議使用默認大小。
自動堆大小需要 bundled JDK ,如果使用自定義JRE位置,則需要Java 14或更高版本的JRE。
如果需要,您可以通過手動 設置JVM堆大小 來覆蓋默認大小
默認情況下,Elasticsearch將JVM配置為將堆內存溢出異常轉儲到默認數據目錄。在RPM和Debian軟體包中,數據目錄是/var/lib/elasticsearch。在Linux、MacOS和Windows發行版上,數據目錄位於Elasticsearch安裝的根目錄下。
如果此路徑不適合接收堆轉儲,請修改 -XX:HeapDumpPath=… jvm.options
默認情況下,Elasticsearch啟用垃圾收集(GC)日誌。這些是在jvm中配置的 jvm.options 並輸出到與Elasticsearch日誌相同的默認位置。默認配置每64mb輪換一次日誌,最多可以消耗2gb的磁碟空間。
您可以使用 JEP 158: Unified JVM Logging 中描述的命令行選項重新配置JVM日誌。除非您更改了默認jvm。選項文件,Elasticsearch默認配置將應用於您自己的設置之外。要禁用默認配置,首先通過提供 -Xlog:disable 選項禁用日誌記錄,然後提供您自己的命令行選項。這將禁用所有JVM日誌記錄,因此一定要檢查可用選項並啟用所需的所有內容。
要查看原始JEP中未包含的其他選項,請參見使用 JVM統一日誌框架啟用日誌記錄 .
Change the default GC log output location to /opt/my-app/gc.log by creating $ES_HOME/config/jvm.options.d/gc.options with some sample options:
Configure an Elasticsearch Docker container to send GC debug logs to standard error ( stderr ). This lets the container orchestrator handle the output. If using the ES_JAVA_OPTS environment variable, specify:
默認情況下,Elasticsearch使用啟動腳本直接在系統臨時目錄下創建的私有臨時目錄。
在某些Linux發行版上,如果最近沒有訪問過/tmp中的文件和目錄,系統實用程序將清除它們。如果需要臨時目錄的特性長時間不使用,那麼在Elasticsearch運行時,這種行為會導致私有臨時目錄被刪除。如果隨後使用需要此目錄的特性,則刪除私有臨時目錄會導致問題。
如果您使用.deb或.rpm包安裝Elasticsearch,並在systemd下運行它,那麼Elasticsearch使用的私有臨時目錄將被排除在定期清理之外。
如果您打算在Linux或MacOS上長時間運行.tar.gz發行版,請考慮為Elasticsearch創建一個專用的臨時目錄,該目錄不在將舊文件和目錄清除的路徑下。這個目錄應該設置許可權,以便只有作為Elasticsearch運行的用戶才能訪問它。然後,在啟動Elasticsearch之前,設置$ES_TMPDIR環境變數指向這個目錄。
默認情況下,Elasticsearch將JVM配置為將致命錯誤日誌寫入默認日誌目錄。對於 RPM 和 Debian 軟體包, 這個目錄是 /var/log/elasticsearch . On Linux and MacOS and Windows 發行版, logs 目錄位於Elasticsearch安裝根目錄下。
這些日誌是JVM遇到致命錯誤(例如分段錯誤)時產生的。如果此路徑不適合接收日誌,請修改 -XX:ErrorFile=... 在 jvm.options 條目。
在災難中,快照可以防止數據永久丟失。快照生命周期管理是對集群進行定期備份的最簡單方法。有關更多信息,請參見備份集群。
在災難中, 快照 可以防止數據永久丟失. 快照生命周期管理 是對集群進行定期備份的最簡單方法. 有關更多信息, 請參見 備份集群 。
備份集群的唯一可靠和受支持的方法是使用快照。您不能通過復制Elasticsearch集群節點的數據目錄來備份該集群。不支持從文件系統級備份恢復任何數據的方法。如果試圖從這樣的備份恢復集群,可能會出現損壞、丟失文件或其他數據不一致的報告,或者看起來已經成功地悄無聲息地丟失了一些數據。
有些設置是敏感的,僅依靠文件系統許可權來保護它們的值是不夠的。對於這個用例,Elasticsearch提供了一個密鑰存儲庫和 elasticsearch -keystore 工具 來管理密鑰存儲庫中的設置。
只有重新啟動Elasticsearch後,對keystore的所有修改才會生效。
這些設置就像elasticsearch中的常規設置一樣。Yml配置文件,需要在集群中的每個節點上指定。目前,所有安全設置都是特定於節點的設置,在每個節點上必須具有相同的值。
Just like the settings values in elasticsearch.yml , 對密鑰存儲庫內容的更改不會自動應用到運行的Elasticsearch節點。重新讀取設置需要重新啟動節點。但是,某些安全設置被標記為 可重新載入 。. Such settings can be re-read and applied on a running node .
所有安全設置的值(無論是否可重新載入)必須在所有集群節點上相同。在進行所需的安全設置更改後,使用 bin/elasticsearch-keystore add 命令, call:
keystore-password : 用於加密Elasticsearch密鑰庫的密碼
此API在每個集群節點上解密並重新讀取整個密鑰存儲庫,但只應用可重新載入的安全設置。對其他設置的更改直到下次重啟才會生效。一旦調用返回,重新載入就完成了,這意味著依賴於這些設置的所有內部數據結構都已更改。所有的設置都應該從一開始就具有新值。
當更改多個可重新載入的安全設置時,在每個集群節點上修改所有安全設置,然後發出 reload_secure_settings 調用,而不是在每次修改後重新載入。
有可重新載入的安全設置:
『捌』 如何查看 java gc 類型
Java中的GC有哪幾種類型?
參數
描述
UseSerialGC
虛擬機運行在Client模式的默認值,打開此開關參數後,
使用Serial+Serial Old收集器組合進行垃圾收集。
UseParNewGC
打開此開關參數後,使用ParNew+Serial Old收集器組合進行垃圾收集。
UseConcMarkSweepGC
打開此開關參數後,使用ParNew+CMS+Serial Old收集器組合進行垃圾收集。Serial Old作為CMS收集器出現Concurrent Mode Failure的備用垃圾收集器。
UseParallelGC
虛擬機運行在Server模式的默認值,打開此開關參數後,使用Parallel Scavenge+Serial Old收集器組合進行垃圾收集。
UseParallelOldGC
打開此開關參數後,使用Parallel Scavenge+Parallel Old收集器組合進行垃圾收集。
在Java程序啟動完成後,通過jps觀察進程來查詢到當前運行的java進程,使用
jinfo –flag UseSerialGC 進程
的方式可以定位其使用的gc策略,因為這些參數都是boolean型的常量,如果使用該種gc策略會出現+號,否則-號。
使用-XX:+上述GC策略可以開啟對應的GC策略。
GC日誌查看
可以通過在java命令種加入參數來指定對應的gc類型,列印gc日誌信息並輸出至文件等策略。
GC的日誌是以替換的方式(>)寫入的,而不是追加(>>),如果下次寫入到同一個文件中的話,以前的GC內容會被清空。
對應的參數列表
-XX:+PrintGC 輸出GC日誌
-XX:+PrintGCDetails 輸出GC的詳細日誌
-XX:+PrintGCTimeStamps 輸出GC的時間戳(以基準時間的形式)
-XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在進行GC的前後列印出堆的信息
-Xloggc:../logs/gc.log 日誌文件的輸出路徑
這里使用如下的參數來進行日誌的列印:
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs
對於新生代回收的一行日誌,其基本內容如下:
2014-07-18T16:02:17.606+0800: 611.633: [GC 611.633: [DefNew: 843458K->2K(948864K), 0.0059180 secs] 2186589K->1343132K(3057292K), 0.0059490 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
其含義大概如下:
2014-07-18T16:02:17.606+0800(當前時間戳): 611.633(時間戳): [GC(表示Young GC) 611.633: [DefNew(單線程Serial年輕代GC): 843458K(年輕代垃圾回收前的大小)->2K(年輕代回收後的大小)(948864K(年輕代總大小)), 0.0059180 secs(本次回收的時間)] 2186589K(整個堆回收前的大小)->1343132K(整個堆回收後的大小)(3057292K(堆總大小)), 0.0059490 secs(回收時間)] [Times: user=0.00(用戶耗時) sys=0.00(系統耗時), real=0.00 secs(實際耗時)]
老年代回收的日誌如下:
2014-07-18T16:19:16.794+0800: 1630.821: [GC 1630.821: [DefNew: 1005567K->111679K(1005568K), 0.9152360 secs]1631.736: [Tenured:
2573912K->1340650K(2574068K), 1.8511050 secs] 3122548K->1340650K(3579636K), [Perm : 17882K->17882K(21248K)], 2.7854350 secs] [Times: user=2.57 sys=0.22, real=2.79 secs]
gc日誌中的最後貌似是系統運行完成前的快照:
Heap
def new generation total 1005568K, used 111158K [0x00000006fae00000, 0x000000073f110000, 0x0000000750350000)
eden space 893888K, 12% used [0x00000006fae00000, 0x0000000701710e90, 0x00000007316f0000)
from space 111680K, 3% used [0x0000000738400000, 0x000000073877c9b0, 0x000000073f110000)
to space 111680K, 0% used [0x00000007316f0000, 0x00000007316f0000, 0x0000000738400000)
tenured generation total 2234420K, used 1347671K [0x0000000750350000, 0x00000007d895d000, 0x00000007fae00000)
the space 2234420K, 60% used [0x0000000750350000, 0x00000007a2765cb8, 0x00000007a2765e00, 0x00000007d895d000)
compacting perm gen total 21248K, used 17994K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)
the space 21248K, 84% used [0x00000007fae00000, 0x00000007fbf92a50, 0x00000007fbf92c00, 0x00000007fc2c0000)
No shared spaces configured.
GC日誌的離線分析
可以使用一些離線的工具來對GC日誌進行分析,比如sun的gchisto( https://java.net/projects/gchisto),gcviewer( https://github.com/chewiebug/GCViewer ),這些都是開源的工具,用戶可以直接通過版本控制工具下載其源碼,進行離線分析。
下面就已gcviewer為例,簡要分析一下gc日誌的離線分析,gcviewer源代碼工程是maven結構的,可以直接用maven進行package,這里編譯的是1.34版本,本版本的快照已經上傳至附件中。
需要說明的是,gcviewer支持多種參數生成的gc日誌,直接通過java –jar的方式運行,載入生成的gc日誌即可: