企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 有效地分发 cron 任务 当你有许多服务器需要执行相同的 cron 作业时,不在同一时间运行它们通常是个好主意。 如果所有作业都要访问一个公共服务器,就会给该服务器带来大量负载, 即使这些服务器不会同时访问公共服务器,所有服务器也会在同一时间处于繁忙状态, 这可能会削减它们提供其他服务的能力。 Puppet 的 inline_template 函数允许我们使用 Ruby 的逻辑根据主机名为 cron 作业设置不同的运行时间。 #### 操作步骤 1. 在一个节点中添加如下代码: ``` define cron_random( $command, $hour ) { cron { $name: command =&gt; $command, minute =&gt; inline_template("&lt;%= (hostname+name).hash.abs %60 %&gt;"), hour =&gt; $hour, ensure =&gt; "present", } } cron_random { "hello-world": command =&gt; "/bin/echo 'Hello world'", hour =&gt; 2, } cron_random { "hello-world-2": command =&gt; "/bin/echo 'Hello world'", hour =&gt; 1, } ``` 2. 运行 Puppet: ``` # puppet agent --test info: Retrieving plugin info: Caching catalog for cookbook.bitfieldconsulting.com info: Applying configuration version '1305713506' notice: /Stage[main]//Node[cookbook]/Cron_random[hello-world]/ Cron[hello-world]/ensure: created notice: /Stage[main]//Node[cookbook]/Cron_random[hello-world-2]/ Cron[hello-world-2]/ensure: created notice: Finished catalog run in 1.07 seconds ``` 3. 检查 crontab 查看是否成功地配置了 cron 作业: ``` # crontab -l # HEADER: This file was autogenerated at Fri Jul 29 10:58:45 +0000 2011 by puppet. # HEADER: While it can still be managed manually, it is definitely not recommended. # HEADER: Note particularly that the comments starting with 'Puppet Name' should # HEADER: not be deleted, as doing so could cause duplicate cron jobs. # Puppet Name: hello-world 25 2 * * * /bin/echo 'Hello world' # Puppet Name: hello-world-2 49 1 * * * /bin/echo 'Hello world' ``` #### 工作原理 我们想要为每个 cron 作业选择一个 **随机的** 执行分钟数; 而不是真正的随机 (或者说,不是每次运行 Puppet 都会改变 cron 作业的运行时间), 但这也或多或少地保证了每个主机上的每个 cron 作业运行时间的不同。 我们可以使用 Ruby 的 hash 方法实现它,它会对任何对象(本例为一个字符串)计算出一个哈希值。 尽管看上去这个哈希值是随机的,但它每次运行时都相同,所以当再次运行 Puppet 时其值不会改变。 哈希值生成的是一个大整数,而我们想要的是一个 0 到 59 之间的整数,所以我们使用了 Ruby 的 % (模)运算符将其结果限制在这个范围内。因为只有 60 种可能的值,尽管 hash 函数被设计为尽可能产生随机的输出,还是会有些许的碰撞而且这些碰撞对于 minute 应该是均匀分布的。 因为我们希望每个哈希值在不同的主机上是不同的,所以使用主机名做 hash 处理。 然而,我们还希望同一台主机上的不同作业的哈希值也不同,所以联合使用了主机名和作业名 (例如 hello-world)做 hash 处理。 #### 更多用法 在本例中,我们仅对 cron 作业的 minute 进行了随机化,并将 hour 作为 define 定义的一部分。若你同时希望指定要在周几运行,可以在 cron_random 中添加一个附加参数来指定, 可以像下面这样为其指定默认值: ``` define cron_random( $command, $hour, $weekday = "*" ) { ``` 若你想要对 cron 作业的 hour 进行随机化(例如:要做的作业可以在一天之内的任何时间执行, 并且必须将它们均匀分布在所有的 24 个小时上),可以对 cron_random 做如下修改: ``` hour => inline_template("<%= (hostname+name).hash.abs % 24 %>"), ``` #### 参见本书 * 第 1 章的 [从 cron 运行 Puppet](#ch01sec05) 一节