订单超时取消实战

102 阅读1分钟

几年前面试时,被问到这个问题。当时,根据市面上常见的几种解决方案进行了回答,比如定时轮询、利用Redis过期机制、RocketMQ延迟消息、被动检测等等。面试官不是很满意,他提了两点点要求:

  1. 实时性,要达到秒级以内
  2. 不能使用外部中间件,比如Redis、MQ等

是不是挺变态?当时没给出满足这两个条件的方案。后来在自研大数据调度平台时,在解决任务调度延迟问题时,突然想到了这个问题,恰好可以顺带解决。实际上解决起来很简单,利用定时轮询+延迟队列就可以解决问题。方案如下:

订单超时解决方案.png

  1. 定时轮询:每隔M分钟从数据库中获取未来N分钟内超时的订单,需满足条件M<N。M、N的设定结合具体情况就好,根据数据库的承载能力以及N分钟内超时订单的数量。
  2. 延时队列:把查询到的订单放入到延迟队列中,一般采用JDK自带的DelayQueue即可。然后,用一个单独的线程不断的轮询延迟队列首节点,判断首节点订单是否超时。没超时就继续轮询,超时就放入处理队列,用一个单独的线程池去处理。

方案呢,想出来后,发现异常简单。实时性几乎可以达到毫秒级,什么中间件也没用。