延时消息项目重一般都能用的到,mq用于解耦,有时可能会用到延时消息(比如定时支付),但是有部分mq暂不支持延时消息,比如kafka,rocketmq支持固定的18个Level延时。当然这些可用其他方案代替,至于用到mq延时的优点后面再说。kafka的优缺点,性能等等百度很多,暂不啰嗦。介绍下kafka延时消费方案。
1.kafka消费消息,按照特定格式判断是否需要延时,若需要,则可以用偏移量和topic位置丢到定时任务框架。当时间达到拿到偏移量和topic位置去kafka获取消息消费。
2.kafka消费消息,按照特定格式判断是否需要延时,若需要,则可以用偏移量和topic位置丢到redis,采用key过期事件实现过期提醒,然后拿到偏移量和topic位置去kafka获取消息消费。或者采用其它第三方手段。
以上去除kafka单独提取都可以实现延时消费,使用kafka优是当消息体较大时,省一部分内存。
插个题外话,redis key过期事件通知有两种
1.当key被访问时,程序会对这个key进行检查,如果key已经过期,那么该key将被删除。
2.定时轮询key是否过期。
当延时消息时间可以达到一周甚至更长,以上实现或许并不是太好的方法,我之前做过多人拼团,拼团过期时间一般可以长达几天。当时采用的mq是rocketmq,kafka消费消息是拉消息,rocketmq消费消息默认是推消息,实现方案是按照时间切割文件,当时是分割成24个文件,一小时一个文件,还有索引文件主要存放偏移量和过期时间,采用时间轮(kafka,netty都存有时间轮)获取临近一小时文件的偏移量,到期获取消息消息体然后推给消费端,理论上支持任意时间延时,但是也意味着io用过及时关闭,所以qps并不会太高,但是符合需求。优化点太多,暂不啰嗦了。