it_worker365

   ::  ::  ::  ::  :: 管理
JDK DelayQueue 内部一个PriorityQueue保存所有的delay对象,堆顶保存了快到期的任务
 
消息相关网站:
1. 客户端轮询服务器获取消息  
2. comet长连接推送消息,实时性,客户端服务器端压力小(如果管理长连接)
 
JS带着用户信息请求长连接,服务器用list/queue保存连接,另起一个线程判断过期,遍历性能太差,只能用有序的queue,但重连复用之后就没序了,所以单一数据结构无法解决
 
以网文为例,检查用户(单机TCP十万级别)是否离线(30S内没消息)。
通用原则:  建立一个map(ID,最后一次消息时间),新来的请求不断更新该map
思路1:
           启动一个timer来轮询这个map。-----只启动一个timer,但轮询效率低
思路2:
           更新并对该ID请求包启动一个timer,30S之后触发。-----启动太多timer耗资源
思路3:
           建立0-30的环形队列,每个slot为一个set<ids>任务集合,还有一个map<id,index>记录每个id投射到哪个slot,启动一个timer让队列每秒移动一格,设置currentIndex指针标志当前位置,当有请求来到,查找map到slot,删除slot对应的id,新增id到currentIndex的上一个位置,更新map。currentIndex每秒清理一个slot。
优点在于只要一个timer,且每秒只运行一次,批量才做超时
 
netty中类似设计:
HashedWheelTimer(高效处理大量定时任务,  且任务对时间精度要求相对不高,  比如链接超时管理等场景, 缺点是,  内存占用相对较高.):
Set<Task>[] 数组, 每个槽位(slot)表示一个 Set<Task>
tickDuration:  每 tick 一次的时间间隔, 每 tick 一次就会到达下一个槽位(上例为1S)
ticksPerWheel: 轮中的 slot 数(上例为30)
如果任务太慢,线程队列单独处理
 
如果任务时间跨度很大,数量多,单个HashedWheelTimer round很大,单个slot中任务列表很长,可以考虑分级HashedWheelTimer
 
posted on 2017-04-10 13:34  it_worker365  阅读(333)  评论(0编辑  收藏  举报