添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

业务需要,要对app用户做个30s离线的功能,即:用户自登录开始,30s内无操作及下线。

常规思路1(单定时器轮询)

  • 用户登录时用关联数组记录用户的uid & 用户最后操作时间,用户的任何操作也要更新对应的操作时间。
  • 开一个定时任务,每秒触发一次,遍历该数组,(操作时间与30s求和)与当前时间比对判断是否该离线

优点
实现简单
缺点
效率较低,用户量一大玩脱,轮询的通病

常规思路2(多定时器)

  • 和思路1一样,需要一个数组记录用户uid和最后操作时间
  • 收到用户操作的请求后开一个定时器,30s后触发,任务内容是,检查该uid最后操作时间是否超过30s,是否该离线处理
    优点
    多定时器,效率高
    缺点
    用户的每次操作都开一个定时器,很耗资源,用户量大也是问题

HashedWheelTimer的实现思路

相信很多同学和我一样第一次看到这个名词,这个结构通俗的讲就是一个环形队列,专门设计用来处理大量定时任务的结构。
先看一张结构图
1.png

原理介绍
为了理解,我们假设业务:用户无操作时,8s即离线处理
如图,该环形队列有8个槽位,每个槽位有index值,定时任务设置为每1s顺时针走1格,聪明的你肯定想到了,我们可以把大量的定时任务通过一套算法落地到每一个槽位,这样当定时任务走到对应槽位时只需要获取该槽位所有的任务去处理即可

  • 8s超时,就创建一个index从1到8的环形队列(本质是个数组)
  • 环上每一个槽位是一个数组(存储uid)
  • 定义一个数组,记录uid落在环形队列的哪个槽位里
  • 启动一个定时器,每隔1s,在上述环形队列中移动一格
  • 定义一个index指针来标识刚检测过的槽的位置

用户请求到达时

  • 从数组中,查找出这个uid存储在哪一个槽里
  • 从这个槽的集合中,删除这个uid
  • 将uid重新加入到新的槽集合中(具体是哪一个槽呢 ,Index指针所指向的上一个槽位,因为这个槽位,会被定时器在10s之后扫描到)
  • 更新数组,记录这个uid对应槽的值
  • 离线操作,定时器每秒种移动一个槽位,这个槽对应的集合中所有uid都应该被集体超时

优点
只需要1个定时器
定时器每1s只需要一次触发,消耗CPU很低
批量超时,当前扫到的槽位集合中所有元素都应该被离线

请关注我的订阅号

系统启一个 定时任务 ,定时扫库,取出超过30分钟的数据,取消释放库存 用户下单后将订单放入MQ的延迟队列(比如RocketMQ的延迟消息),依赖于MQ的通知实时触发取消 将数据放入Redis,定时扫描Redis 将数据放入收尾相连的环形链路中,依次触发超时 二、实现 思路 1、 定时任务 扫库 在分布式定时 在 定时任务 开始执行的时候,CPU都会忽然飙高,但是平时的时候 定时任务 的资源呦没有被用到,为了更好的发挥我们的性能,我们就把每个任务里不同的groupId下的任务平摊到这个时间段里去执行,分散在执行任务那一下资源占用的问题。用redis实现延迟队列是为了持久化,用kafka消息队列其实也可以。redission实现延迟队列。 阿里云日志服务作为云原生可观测与分析平台。提供了一站式的数据采集、加工、查询分析、可视化、告警、消费与投递等功能。全面提升用户的研发、运维、运营、安全场景的数字化能力。 日志服务平台作为可观测性平台提供了数据导入、数据加工、聚集加工、告警、智能巡检、导出等功能,这些功能在日志服务被称为任务,并且具有大规模的应用,接下来主要介绍下这些任务的调度框架的设计与实践。 @Scheduled实现 定时任务 使用@Scheduled注解需要springboot启动类上添加注解@EnableScheduling @SpringBootApplication @MapperScan(basePackages = {"com.xxx.*.mapper"}) @EnableScheduling public class PictureProcessingAdminApplication{ public static void main(String[] args) { Sprin 很多时候,业务有 定时任务 或者定时超时的需求,当任务量很大时,可能需要维护 大量 timer ,或者进行低效的扫描。 例如:58到家APP实时消息通道系统,对每个用户会维护一个APP到服务器的TCP连接,用来实时收发消息,对这个TCP连接,有这样一个需求:“如果连续30s没有请求包(例如登录,消息,keepalive包),服务端就要将这个用户的状态置为离线”。 其中,单机TCP同时在线量约在10w级别,keepalive请求包大概30s一次,吞吐量约在3000qps。 一般来说怎么实现这类需求呢? 今天来说一个Java多机部署下 定时任务 处理 方案。需求: 有两台服务器同时部署了同一套代码, 代码中写有spring自带的 定时任务 ,但是每次执行 定时任务 时只需要一台机器去执行。当拿到这个需求时我脑子中立马出现了两个简单的解决方案:利用ip进行判断, 两台机器ip肯定不一样, 指定某一台机器的ip运行。只在一台机器上部署 定时任务 的代码。最后两个方案又都被自己否决了。 第一条,如果指定ip的机器出现了... 数据服务是数据中台体系中的关键组成部分。作为数仓对接上层应用的统一出入口,数据服务将数仓当作一个统一的 DB 来访问,提供统一的 API 接口控制数据的流入及流出,能够满足用户对不同类型数... 作者:58沈剑 问题抽象:(1)用户会员系统;(2)用户会有分数流水,每个月要 一次分数统计,对不同分数等级的会员 不同业务 处理 ;数据假设: (1)假设用户在100w级别;(2)假设用户日均1条流水,也就是说日增流水数据量在100W级别,月新增流水在3kW级别,3个月流水数据量在亿级别;常见解决方案:用一个 定时任务 ,每个月的第一天计算一次。 //(1)查询出所有用户 uids[] = select... 继续答水友提问。问题抽象:(1)用户会员系统;(2)用户会有分数流水,每个月要 一次分数统计,对不同分数等级的会员 不同业务 处理 ;数据假设:(1)假设用户在100w级别... 我们在实际开发中,多多少少都会用到 定时任务 处理 一些问题。比如金融项目中的对账,每天定时对昨天的账务进行核对,每个月初对上个月的账务进行核对等。还比如,我们需要 处理 一些老数据迁移,修复一些新项目和老项目数据不兼容的问题等等。学习资料的:0 基础 Java 自学之路(配套教程)方案1: Timer 这个目前在项目中用得较少,直接贴demo代码。具体的介绍可以查看api ,但是在某些框架中是有用到。 执行结果: 这么使用,阿里代码检查插件会提示:从提示中可以看出,在多线程并行 处理 定时任务 时, Timer 运行多