00:00
同学们,我们讲一下延迟消息,延迟队列啊。那我们延迟队列的是什么样的概念呢?在讲延迟队列之前,实际上延迟队列呢,就是咱们刚刚讲过的死信队列。的其中的一种。因为死信队列的来源当中有三个来源,第一个叫消息TTL过期。那么这三个来源当中的消息的TTL过期,正是我们马上要讲的延迟队列。那为什么它就是延迟队列呢?是因为这张图同学们看一下。按照这张图来说。我们。哎,我们。这个叫生产者发消息给一个普通的交换机。来到一个普通的队列,如果始终都没有这个C1的话,对吧,这没有这个消费者一,那么他势必一旦过期。
01:01
就势必会成为一个死信。那也就意味着他这个死信到达死信队列,被消费者二所接收。这里面就存在一个问题,就是生产者。对这个位置啊,生产者与消费者。C2啊,一定是C2啊,他们之间。到底经历了多长时间?准确来说应该是经历了,以我们之前的例子来看啊,应该是经历了十秒钟,为什么是经历十秒钟呢?因为你在这个位置发消息,你设置了一个十秒的一个过期时间。到达这个位置,由于长时间没有消费者意义,他在这里面停留了十秒钟,完之后转发到。死信交换机又转发到死信队列完了,消费者二接收到了消息。所以站在这个生产者的角度与C2的消费者的角度来看。
02:05
他们两个之间经历的时间就是十秒。那么这个十秒。其实就是一个延迟嘛。如果你再看把这张图当中。如果C1永远的消失啊,永久消失,再也不出现了。就是没有C这个角色。那么对于这个生产者和C2的消费者来说,他们之间是不是就是一个延迟消息呢?对呀,延迟的时间就是十秒。对,所以我们马上要讲的延迟队列,其实就是死信队列当中的消息过期这一种,因为总共有三种嘛,是吧,其中这一种。就是延迟消息。好,那么我接下来讲一讲延迟消息啊,延迟对立啊。那么颜值队列呢,它是队列内部呢,是有序的,那它是这么一个特点啊,队列内部是有序的,最重要的特点是体现在它的延迟属性上。
03:08
那么延迟队列中元素是希望指定时间的,时间到了以后呢?或者之前取出或处理,这都是不行的是吧?完了呢?简单来说,延迟队列就是用来存放需要指定时间被处理的元素的一个队列。而且延迟队列里面其实存储的就是延迟消息啊,至于延迟多久,完全取决于生产方呗,生产者呗,生产者指定十秒。过期,那么它的延迟时间就是十秒,所以咱们这个延迟队列呢,其实是基于上面死心队列,是基于上面死刑队列。好,接下来我们介绍一下延迟队列的使用场景,在企业上班时,我们这个使用场景非常的多,第一个例如订单在十分钟之内未支付则自动取消。
04:05
那么这个十分钟谁来计算呢?十分钟就有延迟队列来计算,也就意味着当你下了订单之后,你要向延迟队列里发一个消息,这个消息的过期时间为多久?为十分钟?那么十分钟之后,他从延迟队列里出来了,出来之后呢?干什么事儿呢?取消你尚未被支付的订单。就达到了只要十分钟之内未支付,则自动取消订单的这么一个目的。所以这是场景一。场景二。新创建的店铺,如果在十天之内没有上传过商品,则自动发短信提醒。那也就意味着,当用户创建新新店铺的时候,马上发一条消息到延迟堆这里,延迟多久呢?延迟十天。延迟十天,完了呢?十天后消息从延迟队列里出来,完了呢,发现这个店铺依然没有上传商品,则发短信进行提醒。
05:12
这是第二个场景。场景三。用户注册成功后,如果三天内没有登录,则进行短信提醒。那就意味着用户注册成功之后,马上发一个消息到达延迟队列当中。完了呢,多久呢,三天。在延迟队列里待了三天之后出来。判断一下用户是否登录过,发现在这三天之内没有登录过,则进行短信提醒。以此类推。是吧?场景四,用户发起退款,如果三天之内没有得到处理,则通知相关运营人员,还是老方是用户发起退款之后发消息到延迟队列当中。
06:00
存放多久?三天?三天后从岩值队列里出来?判断一下有没有处理,如果没有处理,则通知相关运营人员。场景谷预定会议需要在预定时间点前十分钟通知个人与与会人啊与与参加的会议会议人员。对吧,这个场景。就不好发了,哎,预预定的这个会议的时候,你应该提前十分钟将消息诶塞到延迟队列里,十分钟之后。消息从队列当中出来干什么?通知各各个参会啊,参会人员啊,参与会人员。这些场景都有一个特点,就是需要在某个事件发生之后或者是之前指定时间点完成某一项任务。如发生订单生成事件,在十分钟之后检查该订单状态。
07:01
或者是未支付是吧,如果未支付则进行订单的关闭,看起来似乎呢使用的是定时任务。一直在轮询数据,哎,每秒查一次,取出需要被处理的数据,然后处理不就完事了吗?那如果数据量比较少,确实可以这么做,比如对于如果账单一周内未支付,则进行自动结算。那么这样的需求。如果对时间不是很严格。而是宽松意义上的一周。那么每天晚上跑个定时任务,检查一下所有未支付的账单确实是一个可行的方案。但是对于数据量比较大并且时效性较高的场景,例如订单十分钟之内未支付则关闭,短期内未支付订单数据可能会有很多,所以活动期间甚至可能达到百万甚至千万级别。对于这么庞大的数据量,仍旧使用轮询方式显然是不可取的。
08:00
因为非常耗费性能啊,有可能在一秒之内无无法完成所有的订单的检查。同时会给数据库带来巨大的压力,无法满足业务要求,而且性能低下。这个时候呢,定时器呢就不是很合适了,我们的延迟队列就非常适合这些场景。下面呢,还有一个关于场景的一个一个一个一个一张图啊,这张是一张流程图。这张流程图呢,指的什么意思呢?就是从开始秒杀吧,啊抢购火车票是吧,哎,开始抢购火车票。并且前往付款界面,用户选择付款生成订单,付款状态为零表示未付款。再往下将订单ID等信息一步步录入到队列当中,对这样队列呢?设置了多久呢?30分钟延迟。因为同学们都知道我们买过票啊,都都买过火车票,火车票的时间就是30分钟。
09:01
他会先帮你去抢这个票,抢座,抢完座之后呢,紧接着30分钟之内,如果你不付钱,这个票就回到了人家的系统中,就不再给你买了,所以你付款时间只有30分钟,所以这儿呢。当你不进行付款时,你马上发一条消息到咱们的一个Q的延迟队列里,设置延迟时间为30分钟。如果真到了30分钟,这呢,是否已经过了30分钟,如果是马上被监听器啊,消费者的监听器所监听,监听到之后,这个消费者马上去查询数据库当中该订单记录的付款状态,如果是未付款。对吧,也就是零状态,那么就更新订单状态为已失效,表示已经超过了30分钟仍未付款。完了呢,怎么呢,购买订单的这个数据库更新一下。
10:00
为什么呢?为什么要更新?因为之前这个票是不允许买的,由于这个人也没付钱,自然就把这个票再归还到订单数据库表中,完了更新订单。状态为为什么为已支付?对,如果已支付了,那么就看用户到底30分钟内付没付钱,如果已经付钱了。如果还没有付钱是吧,完了通知。这个东西反了,反了。咱们刚才是30分钟仍为付钱更新数据库,其实更为什么呀,更为此票可以继续再购买,这个时候呢,这呢。用户注意,用户在30分之内如果已经付钱了,那么将订单状态改为一,表示已付款。对吧,那么这呢,还有一个,如果生成订单之后,这个付款状态为零未支付,那么你就需要提醒多久提交提醒用户在30分钟之内付款,这是马上就提醒啊,因为你现在不提醒的一会儿延迟队列,30分钟之后出来还没付钱,他就会取消订单了,把订单改为这个叫失效完,同时将另外一部分。
11:12
就是入库对通知。数据库进行状态的更新。这个呢,就是一个完整的一个购票流程啊。同学们知道一下流程就可以,我们呢,一会儿给同学们演示一下这个延迟队列,哎,是怎么写的,是怎么完成的啊。
我来说两句