发生个很古怪的现象
现在我有一个java程序,使用Springboot框架,程序中有很多使用 @Scheduled
注解的定时器,其中有一个定时器是一分钟执行一次(如下),并且执行开始和结束都会打印相应的日志信息记录,而程序运行在windows系统上的,并且保持开机自启,windows长时间保持运行状态。
@Scheduled(fixedRate = 1 * 60 * 1000) //一分钟
public void executeTask() {
// 定时清除上报集合数据
log.info("Periodically clear the reported collection data,reportTag size:{},reportImage size:{},reportNoread size:{}", reportTag.size(), reportImage.size(), reportNoread.size());
// 这里是执行的任务逻辑
log.info("Periodically clear the reported collection data completed,reportTag size:{},reportImage size:{},reportNoread size:{}", reportTag.size(), reportImage.size(), reportNoread.size());
}
现在呢,由于windows设置可能有问题,导致可能一段时间未操作,导致系统进入了低功耗模式(不知道是休眠还是睡眠)(查询系统日志看到的),然后断电上电重启了windows系统,系统从低功耗模式恢复(系统日志显示),然后程序也会接着运行(程序日志显示程序未重新启动,而是接着上次的执行),这时候看日志发现,这个定时器记录的日志在几十毫秒内记录了几百上千条(一次执行记录两条)。
# 部分日志信息
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
根据观察,每次发现处于低功耗后重启系统,定时器执行后日志的条数,随着低功耗时间的越长而记录的越多。
说明定时器可能是会补充执行低功耗期间未执行的任务的。
首先已经排除了其他原因,因为该程序已经在多个设备上长时间运行正常,且保持程序版本一致,配置一致,系统一致。
而且其他设备上的 Windows 系统设置上不存在系统长时间不操作后处于低功耗这个问题。
观察两天这个异常
我还发现了一个可以论证这个结论的定时器执行日志。
程序中其他部分也有很多定时器,但是很多没有记录日志,但是有一个定时有日志记录,且这个定时器一天执行一次,并且只在凌晨执行一次。
/**
* 在每天的凌晨0点执行任务
* 输出当天的航班统计数据
* 并在输出后清空map
*/
@Scheduled(cron = "0 0 0 * * ?")
public void performTask() {
log.info("Output flight statistics for the day !!!");
// 下面是执行的任务
}
这个定时器本该在凌晨0点时间执行一次,但是由于系统休眠未能执行,但是却在重启系统,系统从低功耗中恢复后,开始执行了一次,相当于补充执行了凌晨低功耗时间没有执行的这个任务。
# 以下是重新启动windows时,程序的部分日志
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:1,reportImage size:1,reportNoread size:2
09:35:37.403 [my-scheduler-10] INFO com.eternal.ynan.YNanRFIDServer - heartBeat, data: {"statusFlag":"3","antnumStatus":"0,0,0,0"}
09:35:37.403 [my-scheduler-8] INFO com.eternal.ynan.YNanBSMServer - Output flight statistics for the day !!!
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
解决办法
禁用 Windows 低功耗
最快的方法当然就是禁用系统的休眠和睡眠模式,防止长时间未操作进入低功耗模式。
要永久关闭 Windows 系统的低功耗模式(包括睡眠和休眠模式),可以通过以下几种方法进行设置:
方法一:通过控制面板关闭睡眠和休眠模式
- 打开控制面板:
- 按
Win + R
键,输入control
并按回车,打开控制面板。
- 按
- 进入电源选项:
- 在控制面板中,选择“系统和安全”。
- 点击“电源选项”。
- 修改电源计划设置:
- 在当前使用的电源计划旁边,点击“更改计划设置”。
- 设置“使计算机进入睡眠状态”选项为“从不”。
- 高级电源设置:
- 点击“更改高级电源设置”。
- 在弹出的窗口中,展开“睡眠”选项。
- 将“睡眠后”和“休眠后”都设置为“从不”。
- 点击“确定”保存更改。
方法二:通过 Windows 设置应用关闭睡眠模式
- 打开设置:
- 按
Win + I
键打开设置应用。
- 按
- 进入系统设置:
- 选择“系统”。
- 进入电源和睡眠设置:
- 选择左侧的“电源和睡眠”。
- 在右侧窗口中,将“在使用电池时”和“插入电源时”的“PC 进入睡眠状态”选项都设置为“从不”。
方法三:通过命令提示符禁用休眠模式
- 打开命令提示符:
- 按
Win + R
键,输入cmd
并按回车。
- 按
- 输入禁用休眠模式的命令:
- 在命令提示符中输入以下命令并按回车:
powercfg -h off
- 这将禁用系统的休眠模式,并删除
hiberfil.sys
文件,从而释放硬盘空间。
方法四:编辑组策略(适用于专业版和企业版)
- 打开组策略编辑器:
- 按
Win + R
键,输入gpedit.msc
并按回车。
- 按
- 导航到电源管理设置:
- 在组策略编辑器中,导航到
计算机配置 > 管理模板 > 系统 > 电源管理 > 睡眠设置
。
- 在组策略编辑器中,导航到
- 禁用睡眠:
- 双击“睡眠状态”设置,将其设置为“已禁用”。
- 禁用混合睡眠:
- 返回到“电源管理”下,找到“混合睡眠策略”,双击并将其设置为“已禁用”。
通过这些方法,您可以永久关闭 Windows 系统的低功耗模式,确保计算机不会进入睡眠或休眠状态。
使用 Linux 系统(推荐)
一般来说,用作服务器使用的系统,都尽量使用 Linux 系统。
尽量避免使用 windows 系统,防止出现一些奇奇怪怪的问题。