多触发策略组合问题解析:Cron 与 TimeBased 是否会重复触发
1 2 3 4 5
| <Policies> <CronTriggeringPolicy schedule="0 0 0 * * ?"/> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="1024 MB"/> </Policies>
|
<Policies> 同时包含了 CronTriggeringPolicy、TimeBasedTriggeringPolicy 和 SizeBasedTriggeringPolicy,核心疑问是 “0 点时是否会触发两个策略(Cron 和 TimeBased)”。下面从 Log4j2 多策略执行逻辑、两种时间相关策略的差异入手,详细分析问题并给出优化建议。
多触发策略的核心执行逻辑
Log4j2 的 <Policies> 是组合触发策略(CompositeTriggeringPolicy),其核心规则是:
只要任意一个策略满足触发条件,就会立即执行日志滚动,且后续策略不再判断(即 “短路执行”,类似if-else的逻辑,而非 “所有满足条件的策略都执行”)。
具体流程如下:
- 日志写入时,Log4j2 按
<Policies> 中策略的配置顺序依次检查;
- 若第一个策略(如
CronTriggeringPolicy)满足条件,则触发滚动,跳过后续策略;
- 若第一个策略不满足,再检查第二个(如
TimeBasedTriggeringPolicy),以此类推;
SizeBasedTriggeringPolicy 会在每次日志写入时检查文件大小,若达到阈值,无论其他策略是否满足,都会优先触发滚动。
0 点时的策略触发分析
配置中,CronTriggeringPolicy(0 点触发)和 TimeBasedTriggeringPolicy(默认按天触发)在 “0 点” 这个时间点看似都满足条件,但实际不会重复触发,原因如下:
1. 两种时间策略的本质差异
虽然两者都与 “时间” 相关,但触发逻辑和依赖条件完全不同:
| 策略 |
触发逻辑 |
依赖配置 |
执行方式 |
CronTriggeringPolicy |
基于 Cron 表达式的定时任务,内部启动独立线程,到时间后主动标记 “需要滚动” |
schedule(Cron 表达式) |
主动触发(与日志写入无关) |
TimeBasedTriggeringPolicy |
基于 filePattern 时间粒度,日志写入时检查当前时间是否超出粒度范围 |
filePattern(如%d{yyyyMMdd}) |
被动触发(依赖日志写入) |
2. 0 点时的实际执行场景