定时任务是常见需求。普遍的做法是,选择一台或几台机器,通过 crontab 实现定时任务。但是对于大规模或大量的定时任务,这种做法的缺点非常多,比如:

  • 可靠性低,一台机器宕机,该机器上的定时任务就无法执行了。
  • 没有调度功能,机器之间的负载可能不均衡。
  • 没有重试机制,任务可能运行失败。
  • 无法运行大规模分布式任务。
容器服务在离线任务的基础上,增加了定时任务的功能,通过简单的描述,解决了上述问题。关于离线任务的详细信息,参见运行离线任务
Note
只有2016年10月25号之后升级了 Agent 版本或新创建的集群才能使用该功能。

基于 Docker Compose 的定时任务描述

同离线任务一样,定时任务也是基于 Docker Compose 的,您只需要在应用模板里添加 aliyun.schedule 标签即可实现定时功能。如下面的例子所示。

Note
定时任务在创建和更新时不会拉取最新镜像,因为使用最新镜像会导致同一个任务在不同的时间使用不同的镜像,会造成排查问题复杂化。建议您通过更改镜像 tag 来变更镜像。
version: "2"
labels:
  aliyun.project_type: "batch"
  aliyun.schedule: "0-59/30 * * * * *"
services:
  s1:
    image: registry.aliyuncs.com/jimmycmh/busybox:latest
    labels:
      aliyun.scale: "5"
      aliyun.retry_count: "3"
      aliyun.remove_containers: "remove-all"
    command: date

说明:

  • aliyun.schedule: "0-59/30 * * * * *"表示每 30 秒执行一次该任务;schedule 的格式和 crontab 完全相同(但要注意 schedule 的格式为 秒 分 时 天 月 星期,比 Linux 上的 crontab 多了秒这一项),使用的时间为北京时间。
  • 因为定时功能只适用于离线任务,所以只要您添加了 aliyun.schedule 标签,系统会自动添加 aliyun.project_type: "batch" 标签,因此上述例子中的 aliyun.project_type: "batch" 可以省略。
  • 另外,离线任务中所有的功能,在定时任务中依然可用,比如 scaleretry_countremove_containers等。有关标签的具体含义,参见运行离线任务

执行过程

定时任务被创建后,应用处于“等待”状态。当任务指定的时间到达时,任务会被启动运行,其后的状态变化和离线应用相同;下一个执行时间到达时,应用状态会重复这一过程。

同一个定时任务同一时刻只会有一个实例在执行,如果任务的执行时间大于其执行周期(比如上述任务的执行时间大于 30 秒),则下一次执行会进入执行队列;如果执行队列长度大于 3,则会丢弃该次执行。

您可以在应用详情页面单击 运行历史查看运行历史及结果,如下图所示。运行历史列表只保留最后 10 次的运行历史。


高可用性

定时任务控制器采用主-从备模式。主控制器故障时,控制功能将切换至备用控制器。

如果任务的执行时刻正好在主从切换期间,则会延迟至切换完成后执行。如果主从切换期间同一个任务有多次执行,切换完成后只会执行一次;因此,为了保证任务不丢失,请不要设计重复周期小于一分钟的任务。