延迟队列,顾名思义,就是带有延迟功能的消息队列。 那么,什么场景下需要这样的队列呢?
一、背景
我们看一下业务场景:
通常,解决上述问题最简单、最直接的方法就是定期扫表。
表扫描的问题是:
延迟队列可以很好的解决上述需求
2. 研究
研究了市场上的一些开源解决方案,如下:
3.- 阿里开源:功能强大,但运维复杂,依赖组件多,不够轻量级
4.-延迟任务:本身没有延迟功能,需要自己借助一个特性来实现,而且公司没有部署这个队列,所以单独部署一个队列来有点贵做一个延迟队列,也需要专门的运维来维护,目前团队不支持
基本上基于以上原因我打算自己写一篇。 我平时经常使用php。 本项目采用基本的redis zset结构作为存储,采用php语言实现。 实现原理参考有赞团队:
整个延迟队列主要由4部分组成
消息结构 每个作业必须包含以下属性:
主题:工作类型。 可以理解为具体的企业名称。
id:作业的唯一标识符。 用于检索和删除指定的Job信息。
:Jod延迟执行时间,13位时间戳
ttr(运行时间):作业执行超时。
body:作业的内容,供消费者做具体的业务处理,以json格式存储。
对于同类型的topic,ttr一般是固定的,作业可以简化属性
ic:职位类型。可以理解为具体的企业名称
2.id:Job的唯一标识符。 用于检索和删除指定的Job信息。
3.body:作业的内容,供消费者做具体的业务处理,以json格式存储。
,ttr是在后台配置的
3. 目标
可扩展性:当消费进程出现瓶颈时,可以配置增加消费进程数。 当写入出现瓶颈时,可以增加实例数量,可以线性提升写入性能
实时:允许一定的时间误差。
支持消息删除:业务用户可以随时删除指定的消息。
消息传输可靠性:消息进入延迟队列后,保证至少被消费一次。
写入性能:qps>1000+
4. 架构设计与描述
整体架构
采用-work架构模式,主要包含6个模块:
5. 模块时序图
留言写:
计时器寻找过期消息:
消费流程:
6. 部署
环境依赖:PHP 5.4+安装、redis、pcntl、扩展
step1:安装数据库,用于存储一些主题和报警信息
dq;
#存储警告信息
表``(
`id`int(11)T,
`主机`(255)'',
`端口`int(11)'0',
`用户`(255)'',
`密码`(255)'',
`分机`(2048)'',
密钥(`id`)
)===utf8;
#存储redis信息
表``(
`id`int(11)T,
“(200)”,
“(2048)”,
密钥(`id`)
)===utf8;
# 存储注册信息
表``(
`id`int(11)T,
“(1024)”,
`延迟`int(11)'0',
“(1024)”,
``int(11)'3000',
`电子邮件`(1024)'',
`主题`(255)'',
“(1024)”,
``(4)'1',
``(32)'获取',
密钥(`id`)
)===utf8;
step2:配置.file中的数据库信息:::$:启动http服务
修改.php文件中的php路径$
命令: