本篇文章阅读时间大约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
那么如何解决呢,暂时没找到好办法,除非应用重启切割日志,好在这个日志只是控制台输出,其余日志中也包含其内容。