最近翻看了去哪儿的QMQ的关于延时队列的源码,主要就是想要了解它在延时队列上实现的设计方案。
![](https://img.haomeiwen.com/i4216420/036e356d53fd89aa.png)
1、延时消息投递到delay-server
2、顺序不断写message log,主要是为了提高性能,写完即响应。
3、回放message log的内容,按照延时时间写到对应的schedule log
4、工作线程从schedule log读取内容后写到内存队列中
5、时间轮线程维护时间轮,并在指针转动的每一次从内存队列中读取数据,按照延时时间依次放入时间轮上的bucket(bucket是一个链表),时间轮的本质是相较于当前时间,延时时间落在时间轮上第几轮的第几格。
long calculated = timeout.deadline / tickDuration;
timeout.remainingRounds = (calculated - tick) / wheel.length;
final long ticks = Math.max(calculated, tick); // Ensure we don't schedule for past.
int stopIndex = (int) (ticks & mask);
6、将到期(超时)的节点(bucket上的node)发送给实时队列,并将对应的Sequence写入到dispatch log.
7、dispatch log的要解决重复发送的问题,但其实这种方案不如将该实现下放给业务
核心类参考:
WheelTickManager
HashedWheelTimer // 时间轮
Receiver // 接收消息类
MessageLog // messgae log
DispatchLog //
ScheduleLog //
ps:相较于滴滴跟美团的方法,还是去哪儿开源的这个延时解决方案更有优势。
网友评论