1.幂等
线上如果多个实例,要考虑任务的幂等。可以给任务做幂等,也可以通过跨实例的中间件去触发。不然肯定会出现什么订单自动签收重复,进而导致部分数据成倍出现,或某值被扣成了负数的场景。
2.时间的合理性
定时任务设置的时间既要避开客户使用高峰期,也要考虑避开夜间的上线时间段,我就遇到过周日凌晨上线,结果服务因为一些原因没起来,导致定时任务没触发的问题。
3.注意大数据量
定时任务必须考虑它可能涉及的数据量,数据量过大,首先肯定会出现慢sql,建议按一定数量分批查询。其次,如果可以的话,尽量不要用线程池。数据量很多时,如果你把数据全仍到等待队列里,可能会产生大量无法立刻回收的对象。或者,如果你线程池最大线程数设的比较大,也可能在一个时刻产生超多的对象。我这里建议是分小批次,一次100,并且创建的任务重不要把全部字段都查出来,可以先查出id,任务开始时再用id去查需要的字段。
4.必须单例
添加@Schedules的类不要设置成多例,即@Scope("prototype"),添加了Schedules注解的类会被相关的spring切面接管,而无法被回收。当该类设置为多例时,每次其他代码调用该类时都会创建一个新的对象,gc一直回收不掉。
5.最好提供手动触发方式和执行日志
最好开发的时候就准备好,不要等到出了问题才想起来加。
6.不要依赖懒加载的代码
任务代码里不要有懒加载设计的代码,懒加载的代码经常会引起“你开发时没问题,实例重启后第一次操作总失败”这种情况出现。尤其是当上线时间设为12点,定时任务设在了凌晨3点。某个类从来没被用过,结果定时任务去用它结果发现没初始化,进而导致任务失败。