智慧充电:异常订单定时任务执行周期 面试回答
2026/9/4 14:45:42 网站建设 项目流程

目录

定时任务多久跑一次?

为什么不用 10s、1 分钟、5 分钟、10 分钟

任务内部判断逻辑(面试必说,区分普通 CRUD)

分布式定时任务防重复执行

面试官延伸问题集合 + 参考答案

Q1:为什么不用短周期,比如 1 分钟执行?

Q2:如果定时任务执行时间超过 3 分钟,下一个任务又触发怎么办?

Q3:有没有考虑过用时间轮、DelayQueue 替代定时任务?

Q4:任务扫描量大,怎么优化 SQL?

Q5:如果定时任务挂掉几个小时,大量僵死订单堆积如何兜底?


业务背景:处理僵死异常订单,设备断电、断网没有上报结束报文,订单一直卡在充电中状态。

定时任务多久跑一次?

生产环境配置:3 分钟执行一次

为什么不用 10s、1 分钟、5 分钟、10 分钟

  1. ❌ 10s / 30s:太频繁。订单表数据量大,每次扫描数据库压力高;大部分订单都是正常状态,大部分扫描都是无效查询。
  2. ❌ 1 分钟:压力还是偏大;设备短暂网络抖动几十秒是正常现象,不要立刻判定为异常订单,避免误关闭正常充电订单。
  3. 3 分钟(我们线上选择)
    • 给设备留出网络抖动恢复窗口期:设备短暂断网 1‑2 分钟,恢复后还可以上报结束报文,优先走正常闭环流程,定时任务作为兜底;
    • 权衡:业务可以接受最多 3 分钟延迟才闭环僵死订单,充电业务这个延迟是运营商可接受;
    • 对 DB 压力可控,配合分页、索引过滤,只扫描状态 = 充电中的订单,不扫全表。
  4. ❌ 5 分钟 / 10 分钟:周期太长。僵死订单不能及时结算,会影响场站统计、用户账单,异常发现滞后。

补充:并不是只要充电中就直接关闭,任务内部有业务判断条件,不是单纯超时。

任务内部判断逻辑(面试必说,区分普通 CRUD)

XXL‑Job 每 3 分钟调度一次:

  1. 查询条件:order_status = 充电中,并且当前时间 - 最后设备上报时间 > 阈值(例如 12 分钟)

关键点:不是看订单创建时间,是看设备最后上报数据时间。 设备一直在上报数据,说明充电还在正常进行,就算订单已经持续 1 小时,也不能关闭。只有设备已经 12 分钟没有任何上报,才判定设备失联,判定为异常僵死订单。

  1. 找到这批异常订单之后:
  • 执行订单强制关闭;
  • 按照已上报电量完成计价结算;
  • 生成最终账单;
  • 记录异常原因(设备失联异常结束);
  • 发送告警通知给运营。

分布式定时任务防重复执行

使用 XXL‑Job:

  • 调度中心统一触发,同一任务同一时刻只会在一个 worker 实例执行,框架层面做了分布式锁,天然避免多实例重复扫描处理。
  • 业务层再加一层:处理订单时,使用数据库乐观锁更新订单状态update t_order set status=已结束 where id=xxx and status=充电中;防止极端情况重复处理同一条订单。

面试官延伸问题集合 + 参考答案

Q1:为什么不用短周期,比如 1 分钟执行?

如果 1 分钟跑一次,大量扫描充电中订单,DBCPU 会抬升。而且充电桩偶尔会出现几十秒网络抖动,如果周期太短,会把暂时断网但是还在充电的订单误关闭。我们给设备留 12 分钟无上报的阈值,任务 3 分钟轮询一次,能及时发现又不误伤正常业务。

Q2:如果定时任务执行时间超过 3 分钟,下一个任务又触发怎么办?

XXL‑Job 配置:阻塞策略 → 单机串行。上一轮没跑完,下一轮调度不执行,避免任务叠加,压垮数据库。同时限制单次处理数量,分页分批处理,不要一次性 load 几万条订单到内存。

Q3:有没有考虑过用时间轮、DelayQueue 替代定时任务?

DelayQueue、时间轮只适合单机。我们是微服务多实例部署,服务重启实例销毁内存任务直接丢失,可靠性不足。异常订单是重要计费业务,不能丢任务,所以选择分布式定时任务 XXL‑Job。

Q4:任务扫描量大,怎么优化 SQL?

索引:idx_status_last_report (order_status, last_report_time),复合索引; 只分页查询满足条件的少量数据,不要一次性查全部;分批处理。

Q5:如果定时任务挂掉几个小时,大量僵死订单堆积如何兜底?

任务恢复后会自动执行;SQL 条件是基于last_report_time时间过滤,会把历史遗留异常订单全部捞出来处理。不会丢失数据。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询