kafka延时队列相关操作

TimingWheel是kafka时间轮的实现,内部包含了一个TimerTaskList数组,每个数组包含了一些链表组成的TimerTaskEntry事件,每个TimerTaskList表示时间轮的某一格,这一格的时间跨度为tickMs,同一个TimerTaskList中的事件都是相差在一个tickMs跨度内的,整个时间轮的时间跨度为interval = tickMs * wheelSize,改时间轮能处理的时间范围在cuurentTime到currentTime + interval之间的事件。

当添加一个时间他的超时时间大于整个时间轮的跨度时, expiration >= currentTime + interval,则会将该事件向上级传递,上级的tickMs是下级的interval,传递直到某一个时间轮满足expiration < currentTime + interval,

然后计算对应位于哪一格,然后将事件放进去,重新设置超时时间,然后放进jdk延迟队列

else if (expiration < currentTime + interval) {
      // Put in its own bucket
      val virtualId = expiration / tickMs
      val bucket = buckets((virtualId % wheelSize.toLong).toInt)
      bucket.add(timerTaskEntry)

      // Set the bucket expiration time
      if (bucket.setExpiration(virtualId * tickMs)) {
        // The bucket needs to be enqueued because it was an expired bucket
        // We only need to enqueue the bucket when its expiration time has changed, i.e. the wheel has advanced
        // and the previous buckets gets reused; further calls to set the expiration within the same wheel cycle
        // will pass in the same value and hence return false, thus the bucket with the same expiration will not
        // be enqueued multiple times.
        queue.offer(bucket)
      }

SystemTimer会取出queue中的TimerTaskList,根据expiration将currentTime往前推进,然后把里面所有的事件重新放进时间轮中,因为ct推进了,所以有些事件会在第0格,表示到期了,直接返回。

else if (expiration < currentTime + tickMs) {

然后将任务提交到java线程池中处理。

你可能感兴趣的:(Kafka)