本篇文章閱讀時間大約2分鐘java
最近公司生產環境服務器常常內存報警,並且多發生在凌晨,見下圖。spring
因爲一直報警,所以寫了一個內存監控的腳本,見上篇文章。最終發現是因爲filebeat致使,懷疑是因爲json相關配置致使,然而發現並不是如此。那咱們書接前文。json
查了下網上關於filebeat內存暴增的資料,發現這樣一篇文章:filebeat 實踐 - 內存佔用 - 最大內存佔用.bash
文章闡述了filebeat內存暴增的緣由,內存公式爲:服務器
$$ bytes_each_log * spool_size * M + a * N $$app
bytes_each_log是指單條日誌大小,spool_size是配置文件裏的配置項,M是單條日誌在內存裏的溢價係數(> 1),N表示採集文件的個數,a爲常數日誌
spool_size的默認值是2048,咱們的配置文件裏也沒設置。具體比照見下表:code
所以若是有單條日誌過大的狀況,內存會突增。因此要設置合適的spool_size值,建議是128或者256.blog
你覺得這樣就結束了嗎,咱們還要深挖緣由,爲何會有單條過大的日誌。這個服務平時壓力並不大,日誌量也很小,不該該出現這種狀況。咱們查找日誌發現有不少二進制字符,以下圖:圖片
日誌文件是stdout.log,這個文件是記錄程序執行的全部控制檯輸出,命令以下:
nohup java ${JAVA_OPTS} -cp ${CLASS_PATH} -jar ${DEFAULT_JAR} --spring.profiles.active=${SERVER_ENVIROMENT} ${APP_NAME}-app >$LOG_PATH/stdout.log 2>&1 &
因爲擔憂時間長文件無限制增加,就定了個計劃任務,每隔兩天清空文件,命令以下:
# clean stdout log 20 02 */2 * * echo "" > /data0/logs/xxxx/stdout.log
正常狀況下程序不會輸出這樣的內容。並且用file命令看文件已經變爲了二進制文件,並未文本文件。以下圖:
咱們繼續檢查爲何會出現這種狀況,懷疑是因爲 echo 清理致使,這時網上發現以下資料:Oh!MongoDB 日誌從文本穿越成了圖片?咋整! 裏面的碰到的狀況跟咱們相似,文件變爲 PCX ver. 2.5 image data
。文章提到:
echo > log
時,會往文件頭部插入 \n
即16進制的 0a
echo > log
是沒法覆蓋的,會將全部數據置爲0
那麼如何解決呢,暫時沒找到好辦法,除非應用重啓切割日誌,好在這個日誌只是控制檯輸出,其餘日誌中也包含其內容。