做到零如何应对海量定时/延迟任务

  

一个系统中存在着大量的调度任务,同时调度任务存在时间的滞后性,而大量的调度任务如果每一个都使用自己的调度器来管理任务的生命周期的话,浪费cpu的资源而且很低效。

  

本文来介绍<代码>从0 中延迟操作,它可能让开发者调度多个任务时,只需关注具体的业务执行函数和执行时间“立即或者延迟”。而延迟操作,通常可以采用两个方案:

  

<代码>时间> 中集合的<代码> timingWheel>   

方案2把维护任务从<代码>优先队阿列(nlog (n)) 降到<代码>双向链表O(1)> O (n)> O (nlog (n))>   

我们先看看<代码>从0 中自己对<代码> timingWheel>   

  

首先我们先来在收集<代码> 的<代码> 中缓存关于<代码> timingWheel>         timingWheel犯错:=NewTimingWheel(时间。第二,插槽,func (k、v接口{}){   关键,好的:=k。(字符串)   如果!好{   返回   }   cache.Del(关键)   })   如果犯错!=nil {   返回nil,犯错   }      缓存。timingWheel=timingWheel      

这是缓存<代码> 初始化中也同时初始化<代码> timingWheel>   

      <李> :<代码>间隔时间划分刻度   <李> <代码> numSlots>   <李> <代码> :执行时间点执行函数   
  

在<代码> 代码缓存中执行函数则是删除过期的关键,而这个过期则由<代码> timingWheel>   

接下来,就通过缓存<代码> 对<代码> timingWheel>   

     //真正做初始化   func newTimingWheelWithClock(间隔时间。持续时间、numSlots int、执行执行股票timex.Ticker) (   * TimingWheel,错误){   tw:=, TimingWheel {   间隔:间隔,//单个时间格时间间隔   股票:股票,//定时器,做时间推动,以间隔为单位推进   槽:使([]*列表。列表、numSlots)//时间轮   计时器:NewSafeMap()//存储任务{键,值}的地图(执行执行所需要的参数)   tickedPos: numSlots - 1,//之前的虚拟圆   执行:执行//执行函数   numSlots: numSlots,//初始化槽num   setChannel:使(chan timingEntry)//以下几个频道是做任务传递的   moveChannel:使(chan baseEntry),   removeChannel:使({})陈接口,   drainChannel:使(陈func({})键,值接口),   stopChannel:使(chan lang.PlaceholderType),   }//把槽中存储的名单全部准备好   tw.initSlots ()//开启异步协程,使用通道来做任务通信和传递   去tw.run ()      返回tw,零   }   之前      

做到零如何应对海量定时/延迟任务

  

以上比较直观展示<代码> timingWheel>   

<代码>去tw.run() 开一个协程做时间推动:

        func (tw * TimingWheel) run () {   为{   选择{//定时器做时间推动→scanAndRunTasks ()   & lt; -tw.ticker.Chan ():   tw.onTick ()//添加任务会往setChannel输入的任务   任务:=& lt; -tw.setChannel:   tw.setTask(任务),   …   }   }   }      

可以看的出,在初始化的时候就开始了<代码>时间> 内部时间段转动,然后底层不停的获取来自<代码>槽> 的任务列表,交给<代码> 执行执行。

  

做到零如何应对海量定时/延迟任务

  

  

紧接着就是设置缓存键<代码> :

        func (c *缓存)组(键字符串值接口{}){   c.lock.Lock ()   _好:=c.data(例子)   c。数据(关键)=价值   c.lruCache.add(关键)   c.lock.Unlock ()      到期:=c.unstableExpiry.AroundDuration (c.expire)   如果好{   c.timingWheel。MoveTimer(关键,到期)   其他}{   c.timingWheel。凝固时间(关键值,到期)   }   }

做到零如何应对海量定时/延迟任务