定单付出胜利后,5分钟后检测下流环节是不是都正常,好比用户购置会员后
一、配景
先看看一下营业场景:
1.会员过期前3天发送召回告诉
2.定单付出胜利后,5分钟后检测下流环节是不是都正常,好比用户购置会员后,各类会员状况是不是都设置胜利
3.若何按期搜检处于退款状况的定单是不是已退款胜利?
4.完成告诉失败,1,3,5,7分钟反复告诉,直到对方答复?
平日处理以上成绩,最简单直接的设施就是准时去扫表。
扫表存在的成绩是:
1.扫表与数据库长时候毗邻,在数目量大的情形轻易泛起毗邻异常中止,需求更多的异常处置惩罚,对法式健壮性请求高
2.在数据量大的情形下延时较高,划定内处置惩罚不完,影响营业,固然可以启动多个历程来处置惩罚,如许会带来额定的保护本钱,不克不及从根本上处理。
3.每一个营业都要保护一个自己的扫表逻辑。 当营业愈来愈多时,发明扫表部份的逻辑会反复开辟,然则异常雷同
延时队列能对上述需求能很好的处理
二、调研
调研了市场上一些开源的计划,以下:
1.有赞科技:只要道理,没有开源代码
2.github个人的:https://github.com/ouqiang/delay-queue
(1)基于redis完成,redis只能设置装备摆设一个,假如redis挂了全部办事不可用,可用性差点
(2)花费端完成的是拉形式,接入本钱大,每一个项目都得去完成一遍接入代码
(3)在star利用的人数不多,放在临盆情况,存在风险,加上对go说话不了解,出了成绩难以保护
3.SchedulerX-阿里开源的: 功用很壮大,然则运维庞杂,依靠组件多,不敷轻量
4.RabbitMQ-延时义务: 自己没有延时功用,需求借助一特征自己完成,并且公司没有布置这个队列,去零丁布置一个这个来做延时队列本钱有点高,并且还需求专门的运维来保护,今朝团队不支撑
根基以上缘由筹算自己写一个,平时利用php多,项目根基redis的zset构造作为存储,用php说话完成 ,完成道理参考了有赞团队:https://tech.youzan.com/queuing_delay/
全部延迟队列主要由4个部份
JobPool用来寄存一切Job的元信息。
DelayBucket是一组以时候为维度的有序队列,用来寄存一切需求延迟的Job(这里只寄存Job Id)。
Timer担任及时扫描各个Bucket,并将delay时候大于等于以后时候的Job放入到对应的Ready Queue。
ReadyQueue寄存处于Ready状况的Job(这里只寄存JobId),以供花费法式花费。
新闻构造
每一个Job必需包括一下几个属性:
topic:Job类型。可以了解成详细的营业称号。
id:Job的独一标识。用来检索和删除指定的Job信息。
delayTime:jod延迟履行的时候,13位时候戳
ttr(time-to-run):Job履行超时时候。
body:Job的内容,供花费者做详细的营业处置惩罚,以json花样存储。
对同一类的topic delaytime,ttr普通是固定,job可以在精简一下属性
1.topic:Job类型。可以了解成详细的营业称号
2.id:Job的独一标识。用来检索和删除指定的Job信息。
3.body:Job的内容,供花费者做详细的营业处置惩罚,以json花样存储。
delaytime,ttr在topicadmin后台设置装备摆设
三、目的
轻量级:有较少的php的拓展就可以直接运转,不需求引入收集框架,好比swoole,workman之类的
稳定性:采取master-work架构,master不做营业处置惩罚,只担任治理子历程,子历程异常加入时主动拉起
可用性:
1.支撑多实例布置,每一个实例无状况,一个实例挂掉不影响办事
2.支撑设置装备摆设多个redis,一个redis挂了只影响部份新闻
3.营业方接入轻易,在后台只需填写相干新闻类型和回调接口
拓展性: 当花费历程存在瓶颈时,可以设置装备摆设加大花费历程数,当写入存在瓶颈时,可增加实例数写入机能可线性进步
及时性:答应存在一定的时候误差。
支撑新闻删除:营业利用方,可以随时删除指定新闻。
新闻传输可靠性:新闻进入到延迟队列后,包管最少被花费一次。
写入机能:qps>1000+