文章目录
前言
刚开始接触的项目流量小,延时关闭订单都是用的定时任务这种,访问量低,数据库压力不大。后面发现访问量高了以后定时任务对数据库压力太大了,不建议使用这种方法,所以我看了下think-queue实现延时任务的实现方法,并自己使用测试了。
下面就是具体实现方法步骤,特别简单。
一、为什么要用延时队列?
(1)最开始我用的都是定时任务(数据库轮询)。服务器搞个定时任务,几分钟跑一次。例如延迟关闭订单,去查询数据库全部待支付订单,然后把超过30分钟未支付的订单关闭。
优点:实现太简单了。
缺点:轮询时间间隔不好确定,占用服务器资源,影响数据库性能。数据库的压力会很大,尤其是订单表数目和用户大了以后,除非极个别情况,不然不建议使用(看了博客上面说的)。
我看了几个方法,对比一下其中的优劣,结合项目实际情况选择了think-queue。
(2)Redis过期回调,利用Redis的key过期回调事件,也能够实现。
我没选择他的主要原因是,一开始我觉得订阅事件会很消耗服务器性能,还有就是要修改Redis的配置,重启服务器。我们服务器挂了好多乱七八糟的项目,还有一些服务任务啥的,我担心有影响。后面看了《请勿过度依赖 Redis 的过期监听》这篇文章,才发现缺点挺致命。
Redis 不能确保 key 在指定时间被删除 , 会造成通知的延期 。
“Basically expired events are generated when the Redis server deletes the key and not when the time to live theoretically reaches the value of zero.”
(3)RabbitMQ的消息队列。这个思路其实跟我要用的Redis的zset有序集合差不多。
消息在发送到消息队列服务端后并不会立马投递,而是根据消息中的属性延迟固定时间后才投递给消费者。
这个优缺点明显,优点:高效,好扩展,支持分布式,换言之就是访问高的大型项目肯定是用这个,面试也会问。
缺点:实现比前面的复杂,维护成本高。
(4)Redis的zset有序集合。
这个是在网上查到的。感觉特别简单,容易实现,对中小型项目友好。具体思路是加入一个延时队列,设置延迟时间执行。这块实现很容易,然后发布监听也很容易,于是我就用了。
二、使用步骤
1.安装Redis
服务器我用的是宝塔,所以很简单。根据自己环境安装。
要配置一下密码。
2.安装think-queue
这里我用的composer。
composer require topthink/think-queue
3.修改配置文件
我是tp6的项目,composer安装完,会在config目录下面生成queue.php的文件。
修改一下配置:
return [
'default' => 'redis', // 默认改成Redis
'connections' => [
'sync' => [
'type' => 'sync',
],
'database' =>