美文网首页Java基础程序员@IT·互联网
10w定时任务,如何高效触发超时

10w定时任务,如何高效触发超时

作者: 高级java架构师 | 来源:发表于2018-09-16 15:18 被阅读0次

一、缘起

很多时候,业务有定时任务或者定时超时的需求,当任务量很大时,可能需要维护大量的timer,或者进行低效的扫描。

例如:58到家APP实时消息通道系统,对每个用户会维护一个APP到服务器的TCP连接,用来实时收发消息,对这个TCP连接,有这样一个需求:“如果连续30s没有请求包(例如登录,消息,keepalive包),服务端就要将这个用户的状态置为离线”。

其中,单机TCP同时在线量约在10w级别,keepalive请求包大概30s一次,吞吐量约在3000qps。

一般来说怎么实现这类需求呢?

“轮询扫描法”

1)用一个Map<uid, last_packet_time>来记录每一个uid最近一次请求时间last_packet_time

2)当某个用户uid有请求包来到,实时更新这个Map

3)启动一个timer,当Map中不为空时,轮询扫描这个Map,看每个uid的last_packet_time是否超过30s,如果超过则进行超时处理

“多timer触发法”

1)用一个Map<uid, last_packet_time>来记录每一个uid最近一次请求时间last_packet_time

2)当某个用户uid有请求包来到,实时更新这个Map,并同时对这个uid请求包启动一个timer,30s之后触发

3)每个uid请求包对应的timer触发后,看Map中,查看这个uid的last_packet_time是否超过30s,如果超过则进行超时处理

方案一:只启动一个timer,但需要轮询,效率较低

方案二:不需要轮询,但每个请求包要启动一个timer,比较耗资源

特别在同时在线量很大时,很容易CPU100%,如何高效维护和触发大量的定时/超时任务,是本文要讨论的问题。

二、环形队列法

废话不多说,三个重要的数据结构:

1)30s超时,就创建一个index从0到30的环形队列(本质是个数组)

2)环上每一个slot是一个Set,任务集合

3)同时还有一个Map<uid, index>,记录uid落在环上的哪个slot里

同时:

1)启动一个timer,每隔1s,在上述环形队列中移动一格,0->1->2->3…->29->30->0…

2)有一个Current Index指针来标识刚检测过的slot

当有某用户uid有请求包到达时:

1)从Map结构中,查找出这个uid存储在哪一个slot里

2)从这个slot的Set结构中,删除这个uid

3)将uid重新加入到新的slot中,具体是哪一个slot呢 => Current Index指针所指向的上一个slot,因为这个slot,会被timer在30s之后扫描到

(4)更新Map,这个uid对应slot的index值

哪些元素会被超时掉呢?

Current Index每秒种移动一个slot,这个slot对应的Set中所有uid都应该被集体超时!如果最近30s有请求包来到,一定被放到Current Index的前一个slot了,Current Index所在的slot对应Set中所有元素,都是最近30s没有请求包来到的。

所以,当没有超时时,Current Index扫到的每一个slot的Set中应该都没有元素。

优势:

(1)只需要1个timer

(2)timer每1s只需要一次触发,消耗CPU很低

(3)批量超时,Current Index扫到的slot,Set中所有元素都应该被超时掉

三、总结

这个环形队列法是一个通用的方法,Set和Map中可以是任何task,本文的uid是一个最简单的举例。

HashedWheelTimer也是类似的原理,有兴趣的同学可以百度一下这个数据结构,Netty中的一个工具类,希望大家有收获

如果想学习Java工程化、高性能及分布式、深入浅出。性能调优、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级程序员群:180705916,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

相关文章

  • 10w定时任务,如何高效触发超时

    一、缘起 很多时候,业务有定时任务或者定时超时的需求,当任务量很大时,可能需要维护大量的timer,或者进行低效的...

  • 10w定时任务,如何高效触发超时

    转自架构师之路 一、缘起 很多时候,业务有定时任务或者定时超时的需求,当任务量很大时,可能需要维护大量的timer...

  • (转载)[架构师之路]10w定时任务,如何高效触发超时

    本系列转载自 【架构师之路】公众号 By 58沈剑。 沈老师擅长用简单的文字把常见原理讲的很透彻,推荐。 一、缘起...

  • 大继的基础级业务实战设计记录(六): 任务系统

    场景 实现一个游戏任务系统 单次,每日,每周,周期... 动作触发任务完成 超时定时器 指定可以完成时间 任务领取...

  • 定时任务框架Quartz

    定时任务框架! 定时任务就是分为三个模块:任务、触发器、调度器 过程就是,调度器协调触发器来再固定时间去触发任务!

  • Go并发的控制

    这里写了个定时任务调度的方案:由定时器去触发一个job,job的执行时间不定,需要有超时处理。这里使用conten...

  • 时钟轮在 RPC 中的应用

    今天这篇文章介绍一下RPC中如何使用时钟轮实现定时任务,比如调用端的超时处理、定时心跳.... 定时任务带来了什么...

  • iOS中的网络和多线程编程(十)

    摘自《iOS程序员面试笔试宝典》 iOS中如何触发定时任务或延时任务 定时任务指周期性地调用某个方法,实现任务的反...

  • Spring job动态修改

    java 中的定时任务quartz,已整合到spring中,如何动态调整任务的触发时间,以下是知识点:

  • 分布式定时任务调度框架

    一、前言 在开发中会有定时任务的场景需要用到定时任务,如订单超时需要自动取消订单、数据需定时备份、定时短信邮件的发...

网友评论

    本文标题:10w定时任务,如何高效触发超时

    本文链接:https://www.haomeiwen.com/subject/tyqfnftx.html