記一次由 echo '' > 引起的問題

本篇文章閱讀時間大約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

10MB 爲 filebeat 支持的單條日誌最大長度,超過的將會被截斷丟棄

所以若是有單條日誌過大的狀況,內存會突增。因此要設置合適的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
  • 在程序正常運行時,log文件是加了鎖的,所以強制執行 echo > log 是沒法覆蓋的,會將全部數據置爲0
  • 所以文件頭部變成了無數的空白

那麼如何解決呢,暫時沒找到好辦法,除非應用重啓切割日誌,好在這個日誌只是控制檯輸出,其餘日誌中也包含其內容。

相關文章
相關標籤/搜索