锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 默认分类
  3. 日常开发部署时要避免的两个打爆磁盘的问题

日常开发部署时要避免的两个打爆磁盘的问题

0
  • 默认分类
  • 发布于 2024-09-23
  • 0 次阅读
黄健
黄健

日常开发部署时要避免的两个问题,处理不当,打爆磁盘,写COE,写 casestudy,怀疑职业选择。

今天来带大家排排雷。

生产日志输出到控制台上

有的同学在开发的时候,自己本机调试,喜欢把日志打到控制台上。方式是在logback.xml或者是log4j2.xml文件中进行了以下的配置(其他语言类似):

<?xml version="1.0" encoding="UTF-8"?><!--configuration:根节点,以下3个属性都是根节点的配置,一般用默认参数即可--><!--scan(扫描): 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true--><!--scanPeriod:多长时间扫描一次,默认60毫秒扫描一次--><!--debug:为true时打印出logback内部日志信息,实时查看logback运行状态,默认是false--><!--日志分几个级别:debug(输出调试信息,一般情况应用程序不会使用debug日志)、info(输出主要信息)、error(输出错误信息)--><configuration scan="true" scanPeriod="60 seconds" debug="false"><!--property:子节点,定义一个变量--><!--name:LOG_PATH日志定义在哪个文件下--><property name="LOG_PATH" value="./logs"></property>    <!--appender:指定日志输出的目的地,目的地可以是控制台、文件等-->    <!--ConsoleAppender:控制台输出-->    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">        <!--layout:布局,输出的日志布局是什么,负责把事件转换成字符串,格式化的日志信息输出-->        <layout>            <!--%d:日期,代表几月几日输出的-->            <!--%thread:线程名,web工程都是多线程-->            <!--%5-level:代表输出级别;级别从左显示5个字符宽度-->            <!--%logger{35}:打出的类名最长35个字符,否则按照句点分割-->            <!--%msg:日志消息-->            <!--%n:换行符-->            <pattern>                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg %n            </pattern>        </layout>    </appender>    <!--root:根节点设置日志级别,设置使用哪些根节点,使用的是appender节点name的值-->    <root level="info">        <appender-ref ref="STDOUT"></appender-ref>    </root></configuration>


上面代码中ConsoleAppender会处理将日志打印到控制台上。

在本机这样调试没有问题,但是到了生产环境,一般需要应用日志与启动日志分离。像上面的配置,root下配置了所有日志都会打印到控制台,而启动日志没有做好日志压缩和滚动清理,就会打满磁盘。

历史日志未清理

机器故障是日常运维中经常出现的问题。一般情况下,机器是可以被修复的,修复时间一般要几天到几个月不等。修复好了,手工一点的公司,会通知开发人员机器已恢复,可以将应用启用了。

然而,应用启动后一段时间磁盘,竟然收到告警说磁盘马上要被打满了。这是怎么回事咧。以logback为例说说日志清理的原理。

<!-- 日志文件输出 --><appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">    <File>${log.base}/${log.moduleName}.log    </File><!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 -->    <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。-->    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">        <FileNamePattern>${log.base}/archive/${log.moduleName}_all_%d{yyyy-MM-dd}.%i.log.zip        </FileNamePattern>        <!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 -->        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">            <maxFileSize>${log.max.size}</maxFileSize>        </timeBasedFileNamingAndTriggeringPolicy>        <maxHistory>${log.max.history}</maxHistory>    </rollingPolicy>    <!-- 日志输出的文件的格式  -->    <layout class="ch.qos.logback.classic.PatternLayout">        <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method\(\):%L -%msg%n</pattern>    </layout></appender>

其中如下定义了压缩和历史日志的保存策略,有两个比较重要的参数:maxFileSize,maxHistory

<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">    <maxFileSize>${log.max.size}</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>${log.max.history}</maxHistory>

先看一下继承关系图

继承关系

maxHistory默认为0,由源码可以看出(TimeBasedRollingPolicy-start()),只有不为0并且清理任务开启标志位true时会触发清理操作
if (maxHistory != INFINITE_HISTORY) {  archiveRemover = timeBasedFileNamingAndTriggeringPolicy.getArchiveRemover();  archiveRemover.setMaxHistory(maxHistory);  if(cleanHistoryOnStart) {    addInfo("Cleaning on start up");    archiveRemover.clean(new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime()));  }}

清理过程会先计算需要清理的时间范围

int computeElapsedPeriodsSinceLastClean(long nowInMillis) {    long periodsElapsed = 0;    //如果尚未执行过清理操作,则默认清理除保留天数外64天以内的日志(由INACTIVITY_TOLERANCE_IN_MILLIS决定)    if (lastHeartBeat == UNINITIALIZED) {      addInfo("first clean up after appender initialization");      periodsElapsed = rc.periodsElapsed(nowInMillis, nowInMillis + INACTIVITY_TOLERANCE_IN_MILLIS);      if (periodsElapsed > MAX_VALUE_FOR_INACTIVITY_PERIODS)        periodsElapsed = MAX_VALUE_FOR_INACTIVITY_PERIODS;    } else {      //如果已经执行过清理操作,则清理从上次到当前时间的需要清理的时间周期。      periodsElapsed = rc.periodsElapsed(lastHeartBeat, nowInMillis);      if (periodsElapsed < 1) {        addWarn("Unexpected periodsElapsed value " + periodsElapsed);        periodsElapsed = 1;      }    }    return (int) periodsElapsed;}

删除时会根据当天时间,生成一个正则表达式:/*****/rsms_all_2018-04-09.(\d{1,3}).log.zip,满足条件的文件就会被清理掉。
由以上可以得出两个结论

  1. 如果首次项目启动时,超出maxHistory定义的时间的64天之前的日志是不会被清理的

  2. 如果当天日志的编号超出3位数后缀,也将不会被清理

总结

上面两个问题其实可能对于很多人来说,理解是很简单的事情。但是有两点需要提醒:

1、要从原理上彻底理解清楚

2、要有良好的规范和方法来避免这样的问题。这一点,目前大多数公司都做不到

标签: #知识库 257
相关文章
最全的办公楼智能化解决方案

最全的办公楼智能化解决方案 2024-10-16 08:40

办公楼综合体智能化如何建设?有哪些系统?近几年,办公楼智能化的项目越来越多,不少项目经理都参与其它,同事办公楼综合体也是弱电系统涉及的最多的项目之一,本期我们一起来看下,最全的办公楼项目智能化设计方案。

规范标准查询、下载网站 2024-10-12 16:41

我们在工作中经常需要用到各种各样的规范标准,这里给大家介绍一些免费查询和下载规范的网站,个人亲测可用。 标准查找查新网站 工标网: http://www.csres.com/ 中国国家标准化管理委员会:http://openstd.samr.gov.cn/bzgk/gb/index 全国标准信息公共

【计算机网络】网络层协议解析 2024-10-08 11:24

网络层的两种服务 IPv4 * 分类编址 划分子网 无分类地址 IPv4地址应用 IP数据报的发送和转发过程 * 主机发送IP数据报 路由器转发IP数据报 IPv4数据报首部格式 ICMP网际控制报文协议 虚拟专用网VPN与

FFmpeg教程(超级详细版) 2024-10-08 11:24

一、参考资料 通过ffmpeg把图片转换成视频 FFmpeg命令(一)、使用filter_complex命令拼接视频 FFmpeg 视频处理入门教程给新手的 20 多个 FFmpeg 命令示例 FFmpeg命令行转码

计算机网络:物理层 —— 数据的传输方式 2024-10-08 11:24

文章目录 * 传输方式 * 串行传输 * 串行传输方式 特点 应用 并行传输 * 特点 应用 网卡的串/并转换 同步传输 * 同步时钟频率的误差问题 特点 应用<

授权码机制 V2.1 2024-10-07 10:26

大家好,我是机灵鹤。 根据读者朋友们反馈的问题和建议,对 授权码 V2.0 版本做了一些优化。 优化内容主要解决了以下几个问题: 优化了授权机制中的时间校验逻辑,避免用户通过回调本地时间来绕过授权机制的问题。 封装和简化了授权接口,开发者可以更方便地接入到自己的程序中。

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.