变小问题
问题现象:
每天上午8点05分,出现acc字段变小
image.png
上面的calc字段是通过物理设备的字段计算得来,acc字段是calc字段的累计值,正常情况下,acc字段不应出现变小
首先怀疑是获取last acc时获取错误
因为acc = last acc + calc
而calc是0,acc变小,可能是last acc获取错误导致
查看代码,看到last acc是先从redis获取,没有则到influx里获取,获取time< 当前时间的最后一条
redis里的缓存则是每次计算后会刷新。这个逻辑看上去没问题
但是如果redis缓存里的数据有误,那么后续数据在这个错误的基础上计算,肯定也都是错误的
所以我们怀疑是redis缓存之前有错误的数据,于是我们把redis清空再继续观察
但是几天后,问题还是出现了
思考为什么每次都是8:05分数据变小?因为每天8点会执行每日重计算,把前一天到今天8点的数据重新计算
所以问题其实是重算的结果和5分钟任务算的结果不一致
不一致是什么时间点开始的,其实很难知道,因为是累计值
为什么不一致?
第一种可能是重算时有对缺失的值进行估值,是不是估值导致的?经过查看,出问题的设备并未估值,所以不是这个原因
第二种可能: 重算时会把一天的所有时间点依次计算,不会少算,但是5分钟任务就不一定了,如果定时器调度失败,那么就漏算了一条。由于acc是累计值,漏算就可能导致数据变小
所以,最大可能就是5分钟任务有漏算,如何保证不漏?
方案1: 调整xxljob参数,增加失败重试次数,串行执行
但是可能导致任务阻塞太多,影响其他任务的调度,不可信
方案2:优化调度方案
xxljob调度时,生成该时间点的任务写入MQ,由MQ的机制保证任务不丢失。
为防止调度失败造成丢任务,在redis里记录当前生成的任务时间点,每次从缓存的时间点往后生成多条任务写MQ
这样通过redis缓存形成一个丢失补偿机制,最多补偿1小时的任务
最终采用此方案