使用Redis实现随机时间任务调度

随机时间任务调度,是指在某个随机时间之后,触发相应的任务。

比如某拼团电商场景中,用户发起拼团后,如果超过一小时没有人加入,会由系统强制添加虚拟用户,强制拼团成功。这个调度时间不能是固定的,而是随机散列分布的,否则会产生虚假感。

以下是用Redis实现的,利用的是redis中zset的排序功能。

首先,需要生成随机时间。在Java中可以用简单的随机算法,

    public Long forceGroupTimeout(OrderGroup group){
        Map<String,Integer> probability=orderGroupConfig.getForceGroupProbability();
        int rd = random.nextInt(100);
        int delay; //结果数字
        if(rd < probability.get("10-30")){ //10-30分钟执行几率
            delay = 10+random.nextInt(20);
        }else if(rd < probability.get("30-60")){//30-60分钟执行几率
            delay = 30+random.nextInt(30);
        }else if(rd < probability.get("60-90")){//60-90分钟执行几率
            delay = 60+random.nextInt(30);
        }else{
            delay = 90+random.nextInt(30);//90-120分钟内强制执行
        }
        Long forceTime = System.currentTimeMillis()+(delay*60*1000)+60*60*1000;//此处添加一小时
        return forceTime ;
    }

其中,probability是一个随机几率的Map,在配置文件里配置如下

forceGroupProbability.10-30: 10

forceGroupProbability.30-60: 20

forceGroupProbability.60-90: 30

forceGroupProbability.90-120: 100

表示10-30分钟执行的几率是10%,30-60分钟执行的几率是20%,最后一个数可以不用填。

生成的这个时间戳就是我们假定一定时间后将要执行任务的时间,将任务id作为key,时间戳作为value保存到redis的zset中。

 

之后,建立每分钟执行的定时任务,使用zset范围取值方法取比当前时间戳小的任务id:

 Set<String> result=zsetOperations.rangeByScore(getRedisKey(),0,currentTimestamp);

取出后根据任务id执行相应的任务,执行完后将对应的key移除即可。

zsetOperations.removeRangeByScore(getRedisKey(),0,currentTimestamp);

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值