延迟队列(一)zset轮询服务

mq因为延迟队列这种有优先级的队列实现很影响性能,所以很多mq都没有很灵活的支持。比如rocketmq,只支持固定的1min,2min什么的延迟时间。

基于redis的zset做延迟队列。
参考:有赞延迟队列设计

大概的思想:
一、把延迟队列独立成一个服务。

1.1 通过http请求,发送put延迟任务。
1)指定topic(比如,订单topic)。
2) id(任务标识)。
3)delay(延迟多久执行)。
4)ttl(job超时时间,超过了多少秒还没有执行,则删除,或者,移入其他地方,之后进行排查,为什么这个任务执行不成功)。
5) body(延迟队列的具体的数据,json格式。比如,订单id)。

1.2 设计数据结构


image.png

1.3 流程
1、客户端,put一个job任务。服务端接收job,放入job pool(job pool是任务存放的真正地方),再根据delay时间,转换成绝对时间,然后以(value:topic 连接 jobid,score:delayTime)按delayTime排序放入redis的zset中。这个zset就是delay bucket。topic和jobid连接时因为,所有的topic统一轮询,一个轮询就够了。
2、有一个timer,轮询delay bucket,如果delayTime大于当前时间,则说明时间到了。只需要遍历zset的前面的元素,前面没有到期,则后面肯定没有到期。比如:每一秒轮询一次,一次轮询,则取出所有到期的job。
3、如果到时间了,则把这个delay bucket中的元素取出来,然后放到,然后解析出topic和jobid, 然后放到对一个的topic的ready queue(这个ready Queue也可以有序,不过无序也没关系)。
4、客户端,每次发送订阅topic请求, 然后这个topic如果没有到期的任务,则把这个http夯住,直到topic有数据,或者,http超时了。所以客户端需要while true不断发送http请求。
5、重试机制怎么做?
每次客户端从服务端拉取任务的时候,要有重试机制,把任务延长5秒,重新放入添加延迟队列,直到超时时间。
6、超时了怎么办?
如果超时了,则可以持久化到数据库,事后运维检查,这些任务为什么会超时。
7、应答机制怎么做?
客户端处理了这个topic后,发送finish给服务端,服务端,把这个任务删掉。
8、客户端处理任务的幂等性要做:比如订单id,则查一下这个订单id是否已处理。或者update where 这种本身就是幂等的操作。

其实有很多细节:

思考:
1、这种机制,其实延迟队列服务端压力不会很大,因为总共也就一秒轮询一次。
2、服务端的压力很大应该来自于,客户端的轮询http,如果每个topic对应一个消费者,然后可能有很多台客户端服务器,也就是一个topic对应很多个http连接。
那么,服务端的服务端连接池可能就几百个上千个。所以,如果topic太多,可能需要扩容。
3、如果扩容的话。上面提到的各个数据结构的操作,可能就要用分布式锁锁住了。
4、客户端一个一个取任务,任务太多的话,网络传输压力太大,可以考虑,一次指定取多少个,如果没有这么多个,则有多少个取多少个。

缺点:
1、需要引入一个定时服务器。所以,如果数据库轮询能处理,就数据库轮询吧。
1、http轮询,比较麻烦。最好时做到mq那样,直接推。
2、总感觉,这种方式很麻烦。

这里有一个别人的实现:这里有一些地方值得商榷,比如,分布式锁方面(他没有做),消息重试方面(无限重试,客户端收到消息后,把过期时间设置到超时时间,然后重新放入队列),消息超时方面(消息超时无限重试)。http轮询方面。
但是,如果有需要,可以直接修改这个代码,或者直接推翻重写。只是作为一个参考。
https://github.com/yangwenjie88/delay-queue.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容