producer向kafka扔一条消息,consumer立刻就会消费,那你有没有遇到过希望一段时间之后再让consumer消费的场景呢?
假设某电商网站的用户生成了一个新的待支付订单,你希望30分钟后如果用户还未支付,就将订单关闭,应该怎么做呢?
kafka本身不支持延时消费,只能有我们来实现这个中间件。先来看看redis的有序集合类型SortedSet,有序集合类型底层的数据结构是"哈希表+跳跃表",也就是说你的一份数据,其实有序集合存储了两份。哈希表可以支持精准查找(针对key),跳跃表支持范围查找(针对score),如果我们要找到score最小的值,时间复杂度是O(1)。而插入一条数据的平均时间复杂度是O(logN)。
我们简化模型,假设将订单ID作为key,下单时间+30分钟时间戳作为score存储,zadd zdelayMsg timestamp1 orderid1 timestamp2 orderid2 ...。这样我们只需每次取出score最小的值,就可以判断是否到达了检测时间,伪代码:
如果你希望将延时消息的功能推广到全公司,避免大家重复开发,你也可以多一些封装.
由各个业务线自己组装所需要的info_detail信息,再生成唯一键info_key
zadd zdelayMsg timestamp info_key
hset hdelayMsg info_detail info_key
把消息扔进消费队列时,携带上info_detail。这样在kafka处理的时候,根据callback以及params就可以知道需要调用的具体函数或者远程api接口了。