有业务线提出需求:要求对于其流量,只能在0点到7点扫描。
对此,celery发送任务到队列时可以指定执行的时间。
当worker收到任务后,判断还未到执行时间,会存储在worker中,在到达时候后再执行。
如果还未执行就中断worker,则任务会重新打回celery队列中,不担心丢失。
所以只需要传入time格式的具体执行时间就行。
Demo
import datetime def in_run_time(start, end): """ 用来给任务判断,在不在可执行的时间里,是不是需要丢到定时里 Args: start: 任务开始执行的时间,格式如 "00:00:00" end: 任务停止执行的时间,格式如 "07:00:00" Returns: """ current_date = str(datetime.datetime.now().date()) + " " start_time = datetime.datetime.strptime(current_date + start, '%Y-%m-%d %H:%M:%S') end_time = datetime.datetime.strptime(current_date + end, '%Y-%m-%d %H:%M:%S') current_date = datetime.datetime.now() if (start_time < current_date) and (current_date < end_time): return True else: return False def get_nextday_run_time(start, end): """ 根据当前时间,和起止时间,得出该任务应该执行的时间。 Args: start: 任务开始执行的时间,格式如 "00:00:00" end: 任务停止执行的时间,格式如 "07:00:00" Returns: """ current_date = datetime.datetime.now().date() end_time = datetime.datetime.strptime(str(current_date) + " " + end, '%Y-%m-%d %H:%M:%S') current_time = datetime.datetime.now() # 如果现在还没到今天的执行时间,那么任务放到今天的执行时间来执行 if current_time > end_time: current_date += datetime.timedelta(days=1) run_time_str = str(current_date) + " " + start # 执行-北京时间 run_time = datetime.datetime.strptime(run_time_str, '%Y-%m-%d %H:%M:%S') run_time = run_time + datetime.timedelta(hours=-8) return run_time def get_run_time_by_bj_time(bj_time): """ 将时间格式字符串转换为datetime格式 Args: bj_time: 指定执行时间 type-str 如 "2019-08-21 13:21:00" Returns: """ run_time = datetime.datetime.strptime(bj_time, '%Y-%m-%d %H:%M:%S') run_time = run_time + datetime.timedelta(hours=-8) return run_time start = "00:00:00" end = "07:00:00" work.apply_async(args=[scan_data], eta=get_nextday_run_time(start, end), queue="队列名,没有可删除参数", routing_key="队列key,没有可删除参数")