消息队列使用介绍:
在很多场景下我都有用到消息队列,有的使用Kafka,有的用RabbitMQ等都能满足消息的生产和消费,但是延迟队列呢?怎么设计,但能配合代码+数据库+MQ也能实现,只是逻辑繁琐一点。
需求背景:
大家都用过支付宝|微信,都有对应的支付通知功能,且是有频次控制的哦,(像支付宝:如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h),这种场景就可以设计对应的延迟队列来处理了)
Redis设计延迟队列:
Redis的有序集合天然支持这种场景,
zAdd('notify_msg_queue', '1553053550', '1553053550-1234567891-0');//值:当前时间戳-订单号-通知次数
$redis->zRangeByScore('notify_msg_queue', 0, '1553053550');//排序因子用时间戳,这样能去除之前到现在的所有数据
zRem('notify_msg_queue', '1553053550-1234567891-0');//指定删除对应的值
设计原理:队列名字为:notify_msg_queue,因子为当前时间戳,值为【当前时间戳-订单号-通知次数】,获取的时候
如果通过zRangeByScore拿到对应的值能后处理值,根据 “-”符号分割值,如果时间戳 <= ,能后根据订单好通知业务方
的通知接口,如果通知成功则zRem删除对应值从消息队列中移除,如果通知是吧删除原来的值,重新赋新值入消息队列:历史时间戳+4分钟(若都是败就依次增加:4m,10m,10m,1h,2h,6h,15h,知道15h后),
总结:
这种场景很常用,使用异步形式通知(定时任务|守护进程之类的来处理效率高点)
编辑:乐杨俊