Cron Job:服务器维护必须掌握的必杀技

Cron Job:服务器维护必须掌握的必杀技

你想每天凌晨两点起床,清理日志、清理临时文件,然后运行相同的服务器维护任务吗?

好吧,我也不想。管理着全球超过 140 亿台服务器的数百万服务器管理员也不想。

所以,别再胡闹了——我求求你!

Cron 作业就是为此而生的。

因为,说实话,没有什么比沉睡并将脚本为你完成的工作据为己有更能体现“称职的系统管理员”的了。这叫做“利用你的资源”。

有了 Cron 作业:

  • 你的老板认为你很敬业。
  • 你的服务器知道你很懒。
  • 你们之间存在着一种美好的共生关系,叫做自动化。

今天,你将成为一名 Cron 作业专家。

什么是Cron Job?

Cron job 本质上是类 Unix 操作系统(Linux、macOS)内置的任务调度程序,可让您在指定的时间和日期自动运行 Linux 命令

您可以将其想象成服务器的待办事项列表,但……这个待办事项确实会完成。

Cron的隐喻

如果你的服务器基础设施是餐厅:

  • cron daemon 就像是查看每日日程安排的经理。
  • crontab 是员工分配板。
  • 每个 cron job 都是在特定时间分配给特定员工的任务。
  • command 是实际正在执行的工作。

当时钟到达预定时间时,经理会拍拍被分配员工的肩膀说:“表演时间到了!”

然后,员工会毫无异议地执行他们的任务。

如果我们人类也能如此可靠,世界将会变得截然不同!

Cron Job的剖析

每个 Cron 作业都包含两个主要部分:

  1. 何时运行(计划)
  2. 运行什么(要执行的命令或脚本)

计划使用一种特定的语法,乍一看可能像是某种计算机魔法:

Cron Job的剖析

但仔细观察,你就会明白。

每个星号都可以替换为特定的值、范围或间隔,从而精确地创建你所需的计划。

服务器管理员为何钟爱Cron Job

服务器管理员(甚至包括我)在讨论 Cron 作业时会眼眶湿润是有原因的。

它们将服务器管理变成了(至少在某种程度上)类似于工作与生活平衡的事情。

1. 节省时间

还记得时间吗?那件你永远觉得不够用的东西?Cron 作业会把时间还给你。你设置了它们,然后就忘记了,而且你几乎从来不会去看它们。

(嗯,直到它们崩溃或者你需要更改计划。)

2. 保持一致性

人类的本性是不一致的。我们会忘记事情。我们会打错字。我们会被猫咪视频分散注意力。而 Cron 作业每次都以完全相同的方式执行完全相同的任务——没有例外。

3. 您的服务器永不休眠

有了 cron 作业,无论您是醒着、睡着,还是在海滩上啜饮玛格丽塔鸡尾酒,基本维护工作都可以 24/7/365 全天候进行。

4. 错误日志 > 人类记忆

当您手动执行任务时,您能准确地记住自己做了什么以及何时做的吗?可能记不住。

但是,您可以配置 cron 作业来记录其活动,从而创建所有自动化操作的纸质记录,以便进行故障排除和验证。

5. 专为可扩展性而构建

随着您的基础设施规模不断扩大,手动管理所有操作的难度将呈指数级增长。而 cron 作业则可以轻松扩展。

这意味着,同一项作业可以在多台服务器上运行,而无需您投入额外的时间。

设置Cron Job:分步指南

理论知识讲得够多了!你需要亲自动手,进行一些实际的 Cron job 设置。

步骤 1:确认Cron已安装

大多数类 Unix 系统都预装了 Cron。要检查它是否可用,请输入以下命令:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
crontab -e
crontab -e
crontab -e

根据默认编辑器,该命令将使用您指定的编辑器打开 crontab。如果您以前从未使用过 crontab,它可能会要求您设置默认编辑器。

打开 crontab

如果终端显示“command not found”,则需要使用以下命令安装 cron:

  • Ubuntu/Debian:sudo apt update && sudo apt install cron
  • CentOS/RHEL:sudo yum install cronie

完成后,启动并启用 cron 服务:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
sudo systemctl start cron
sudo systemctl enable cron
sudo systemctl start cron sudo systemctl enable cron
sudo systemctl start cron
sudo systemctl enable cron

使用 startenable 命令,我们将启动 cron 服务来执行 cron 任务。

使用 enable 命令,我们可以确保即使您的服务器重启,cron 服务也会自动重启,并且不会错过任何 cron 任务。

提示:CentOS 将 cron 服务称为“crond”,因此您需要启动并启用 crond 服务。

步骤 2:了解Crontab

好的,打开 crontab 或 crontable 开始添加您的计划任务。

系统中的每个用户都可以拥有自己的 crontab 文件。此外,还有一个系统范围的 crontab。

要编辑您的个人 crontab:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
crontab -e
crontab -e
crontab -e

这将在您的默认文本编辑器中打开您的 crontab 文件。如果这是您第一次使用,请选择 nano 编辑器(选项 1),因为它最适合初学者。

对于系统级 crontab,请使用 sudo 权限运行以下命令:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
sudo nano /etc/crontab
sudo nano /etc/crontab
sudo nano /etc/crontab

系统级 crontab

步骤 3:Cron Job语法

我们之前已经讨论过 Cron 作业的基本结构。

但是,创建 Cron 作业有时会令人困惑。Crontab.guru 可以帮助您在输入作业计划时将其可视化。

Crontab.guru

现在到了有趣的部分——编写我们的第一个 Cron 作业。让我们来看看一些常见的 Cron 作业计划:

每分钟:

* * * * /path/to/command

每小时 0 分钟:

0 * * * * /path/to/command

每天午夜:

0 0 * * * /path/to/command

每周一凌晨 3 点:

0 3 * * 1 /path/to/command

每15分钟:

*/15 * * * * /path/to/command

每月第一天上午 6:30:

30 6 1 * * /path/to/command

步骤 4:创建您的第一个Cron Job

让我们开始为您的服务器创建一个简单的备份 Cron 作业。

以下任务每天凌晨 2 点创建您网站的备份

0 2 * * * tar -czf /path/to/backup/website-backup-$(date +%Y%m%d).tar.gz /path/to/your/website

它将输出您的网站目录的压缩 tar 存档,并以当前日期作为文件名。

步骤 5:保存并验证

现在,退出编辑器。在 nano 中,按下 Ctrl+X,然后按 Y。

要查看当前的 crontab 并验证您的任务是否已添加:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
crontab -l
crontab -l
crontab -l

验证您的任务是否已添加

就这样!您的第一个 cron 作业现已设置完毕,并将在预定时间自动运行。

面向网站管理员的实用cron job示例

现在您已经了解了基础知识,让我们来探索一些实用的 cron 作业,它们可以显著简化您作为网站管理员的工作。

数据库备份

MySQL 数据库备份(每天凌晨 1 点):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 1 * * * mysqldump -u username -p'password' database_name | gzip > /path/to/backups/db-backup-$(date +%Y%m%d).sql.gz
0 1 * * * mysqldump -u username -p'password' database_name | gzip > /path/to/backups/db-backup-$(date +%Y%m%d).sql.gz
0 1 * * * mysqldump -u username -p'password' database_name | gzip > /path/to/backups/db-backup-$(date +%Y%m%d).sql.gz

日志轮换和清理

清理超过 7 天的日志(每周日):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 0 * * 0 find /path/to/logs -type f -name "*.log" -mtime +7 -delete
0 0 * * 0 find /path/to/logs -type f -name "*.log" -mtime +7 -delete
0 0 * * 0 find /path/to/logs -type f -name "*.log" -mtime +7 -delete

网站性能监控

每 5 分钟检查一次网站响应时间:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
*/5 * * * * curl -o /dev/null -s -w "%{http_code} %{time_total}sn" example.com >> /path/to/logs/website-performance.log
*/5 * * * * curl -o /dev/null -s -w "%{http_code} %{time_total}sn" example.com >> /path/to/logs/website-performance.log
*/5 * * * * curl -o /dev/null -s -w "%{http_code} %{time_total}sn" example.com >> /path/to/logs/website-performance.log

内容更新

获取并更新动态内容(每小时):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 * * * * /path/to/content-update-script.sh
0 * * * * /path/to/content-update-script.sh
0 * * * * /path/to/content-update-script.sh

电子邮件报告

每周一上午 9 点发送每周流量摘要:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 9 * * 1 /path/to/generate-and-email-report.sh
0 9 * * 1 /path/to/generate-and-email-report.sh
0 9 * * 1 /path/to/generate-and-email-report.sh

安全扫描

每天凌晨 3 点运行安全扫描脚本:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 3 * * * /path/to/security-scan.sh
0 3 * * * /path/to/security-scan.sh
0 3 * * * /path/to/security-scan.sh

Cron Job最佳实践:注意事项

为了确保您的 Cron 作业顺利运行,避免问题多于其解决的问题,以下是一些重要的最佳实践。

应该

  1. 始终使用命令和文件的完整路径:您的 Cron 环境与用户 Shell 的 PATH 不同,因此 "/usr/bin/python" 比使用 python 更好。
  2. 重定向输出以防止垃圾邮件:默认情况下,Cron 会将所有输出通过电子邮件发送给用户。添加 >/dev/null 2>&1 可以抑制输出,或重定向到日志文件。
  3. 在调度命令之前测试它们:手动运行命令以确保其按预期工作。

添加注释来解释每个作业——将来您会感谢您记录每个 Cron 作业的功能及其原因。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Daily database backup - Added by Jane on 2023-05-15
0 1 * * * /path/to/backup-script.sh
Daily database backup - Added by Jane on 2023-05-15 0 1 * * * /path/to/backup-script.sh
Daily database backup - Added by Jane on 2023-05-15
0 1 * * * /path/to/backup-script.sh

考虑对长时间运行的作业使用锁文件,以防止在前一个实例仍在运行时启动新实例。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 * * * * flock -n /tmp/script.lock /path/to/your/script.sh
0 * * * * flock -n /tmp/script.lock /path/to/your/script.sh
0 * * * * flock -n /tmp/script.lock /path/to/your/script.sh

不应该

  1. 不要在高峰时段安排资源密集型任务:您的备份无需在站点最繁忙的中午运行。
  2. 不要使用相对路径:"./script.sh" 在 cron 中几乎肯定会失败。
  3. 不要忘记环境变量:Cron 不会加载您的 .bashrc 或 .profile 文件。请在 crontab 或脚本中设置所有必要的变量。
  4. 不要忽视日志记录:如果没有适当的日志记录,调试 cron 任务可能会成为一场噩梦。
  5. 不要过度:过多频繁的 cron 任务可能会导致服务器过载。要有策略性。

Cron Job出错时该怎么办

只有在 Cron 作业中断时才需要回顾它——当它中断时,以下是如何诊断和修复常见问题的方法。

常见问题 #1:作业无法运行

症状:您的计划任务似乎根本没有执行。

可尝试的修复方法:

  • 检查 Cron 守护进程是否正在运行:“systemctl” status cron
  • 验证您的 crontab 语法:使用类似 crontab.guru 的工具
  • 确保可执行文件的完整路径:使用哪个命令查找完整路径
  • 检查文件权限:脚本必须是可执行的 (chmod +x script.sh)

常见问题 #2:作业运行但失败

症状:作业执行但未成功完成其任务。

可尝试的修复方法:

  • 将输出重定向到日志文件以查看错误: * * * * /path/to/script.sh > /path/to/script.log 2>&1
  • 在相同环境下手动测试该命令
  • 检查 cron 环境中可能缺少的依赖项

常见问题 #3:邮件泛滥

症状:您的收件箱被 cron 输出邮件淹没。

可尝试的修复方法:

  • 将输出重定向至 null:>/dev/null 2>&1
  • 重定向至日志文件:>/path/to/logfile.log 2>&1

仅在发生错误时发送电子邮件:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
* * * * /path/to/script.sh >/dev/null || echo "Script failed" | mail -s "Cron failure" you@example.com
* * * * /path/to/script.sh >/dev/null || echo "Script failed" | mail -s "Cron failure" you@example.com
* * * * /path/to/script.sh >/dev/null || echo "Script failed" | mail -s "Cron failure" you@example.com

常见问题 #4:时间问题

症状:作业在非预期的时间或频率运行。

可尝试的修复方法:

  • 仔细检查您的时区设置——日期与 cron 的预期时间
  • 注意可能影响时间的夏令时 (DST) 变化
  • 当精度要求较高时,请使用明确的时间框架,而不是相对时间框架

高级Cron Job编写技巧

我们已经了解了基础知识,现在您已经是 Cron 作业的专家了。但本节将带您更进一步。

使用特殊字符串

您不必总是使用星号来编写 Cron 作业。有一些特殊字符串可以让您轻松设置 Cron 作业。

  • @yearly 或 @annually:每年运行一次 (0 0 1 1 *)
  • @monthly:每月运行一次 (0 0 1 * *)
  • @weekly:每周运行一次 (0 0 * * 0)
  • @daily 或 @midnight:每天运行一次 (0 0 * * *)
  • @hourly:每小时运行一次 (0 * * * *)
  • @reboot:启动时运行一次

例如,如果您希望每天运行某些程序,只需输入以下命令:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@daily /path/to/daily-backup.sh
@daily /path/to/daily-backup.sh
@daily /path/to/daily-backup.sh

Crontab中的环境变量

为了避免在 cron 作业中反复重复输入某个字符串(例如,指定路径或管理员邮箱),请在 crontab 的开头设置环境变量。

然后,您可以在脚本或命令中根据需要重复使用这些变量。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
# This job will send errors to admin@example.com
0 2 * * * /path/to/mailing_script.sh
SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MAILTO=admin@example.com # This job will send errors to admin@example.com 0 2 * * * /path/to/mailing_script.sh
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
# This job will send errors to admin@example.com
0 2 * * * /path/to/mailing_script.sh

如果我们在 mailing_script.sh 中使用环境变量 MAILTO,脚本将自动向正确的电子邮件地址发送电子邮件。

这样,更改管理员电子邮件地址只需更改 MAILTO 变量的值,而无需在所有脚本中进行更改。

以不同用户身份运行作业

如果您拥有超级用户权限,则可以编辑其他用户的 crontab:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
sudo crontab -u username -e
sudo crontab -u username -e
sudo crontab -u username -e

在非常开机的机器上使用Anacron

与 cron 不同,anacron 即使在计划时间内计算机处于关闭状态,也能确保作业运行:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
sudo apt install anacron
sudo apt install anacron
sudo apt install anacron

编辑 /etc/anacrontab 以添加系统恢复在线时将运行的作业。

复杂工作流程的作业链

按顺序运行作业:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 1 * * * /path/to/first-script.sh && /path/to/second-script.sh
0 1 * * * /path/to/first-script.sh && /path/to/second-script.sh
0 1 * * * /path/to/first-script.sh && /path/to/second-script.sh

监控Cron Job

对于严肃的服务器管理,可以考虑使用 Cronitor 等工具来监控和提醒您的 Cron 作业。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
0 * * * * cronitor exec check-12345 -- /path/to/your/script.sh
0 * * * * cronitor exec check-12345 -- /path/to/your/script.sh
0 * * * * cronitor exec check-12345 -- /path/to/your/script.sh

谈谈成本

Cron 作业不能孤立存在。它们需要一台服务器以及运行在服务器上的一项服务,而您需要管理这些服务。

现在,如果您正在阅读这篇文章,那么您很可能已经拥有一台用于运行网站或应用程序的服务器。

事实上,如果您使用 VPS 或任何基于 Linux 的主机提供商,那么您已经具备了开始自动化服务器管理任务所需的一切。

如果没有,那么每月 10 美元的 VPS 就足够了,尤其是在刚开始使用时。

对于已经在使用 VPS 的用户来说,流程非常简单:

  1. 通过 SSH 连接到您的服务器
  2. 运行 crontab -e 编辑您的个人 cron 表
  3. 添加您的计划任务
  4. 保存,然后开始自动化!

就是这样。您已经付费的基础设施突然变得更有价值、更高效。

写在最后

您已从体力劳动晋升到自动化魔法师的行列。有了 cron 作业处理日常维护、备份和监控,您可以专注于发展网站和业务,而无需操心服务器的日常维护。

请记住,这将是一个过程。随着您添加越来越多的任务,自动化将变得更加复杂。

但现在,请先从几个基本的 cron 作业开始,监控它们的运行情况,并随着您对流程的熟悉逐渐扩展您的自动化功能。

现在,去休息吧,因为您刚刚节省了一大笔时间。

评论留言