پرش به مطلب اصلی

Cron Job‌ها


در بعضی اوقات نیاز است که سرویس شما یک کار خاصی را به صورت دوره ای انجام دهد. معمولا برای این کار در برنامه‌ها از Cron Job ها استفاده می‌شود. استفاده از Cron Job ها در سرویس‌های چابکان بسیار ساده می باشد. در این قسمت از مستندات چابکان آموزش استفاده از Cron Job ها را فرا خواهید گرفت.

برای استفاده از Cron Job ها کافیست یک فایل به نام cron-jobs در داخل ریشه اصلی هاست ابری ایجاد کنید و دستورات Cron Job خود را داخل آن قرار دهید.

دقت کنید

عملیات‌های مشخص‌شده در فایل cron-jobs در زمان اجرای اولیه سرویس کپی می‌شوند. بنابراین برای اعمال تغییرات این فایل و تاثیر آن در هاست ابری، می‌بایست سرویس را ری‌استارت کنید.

Cron Jobs در هاست ابری

برای استفاده از Cron Job در هاست ابری می‌بایست فایل cron-jobs را در مسیر اصلی پروژه /app ایحاد کنید. مسیر کامل فایل به این شکل خواهد بود:

/app/cron-jobs
توجه

در سرویس‌های php و laravel مسیر اصلی پروژه برابر است با /var/www/html.

نمونه فایل cron-jobs:

cron-jobs
* * * * * cd /var/www/html && /usr/bin/php artisan schedule:run >> /var/log/laravel-scheduler.log 2>&1

با استفاده از کامند بالا، scheduler لاراول هر دقیقه اجرا می شود.

توجه

بعد از تنظیم فایل، برای شناسایی کرون جاب توسط برنامه، سرویس خود را ری‌استارت نمایید.

Cron Jobها در سرویس Docker

ایجاد Cron Job در سرویس Docker چابکان روش متفاوتی دارد که در ادامه به توضیح آن می‌پردازیم.

برای استفاده از Cron Job در سرویس‌ Docker می‌بایست فایل حاوی دستورات cron را (با هر نام دلخواه) در مسیر دلخواه ایجاد کنید.

نکته

در سرویس‌ Docker فایل cron job را با هر نام و در هر مسیر دلخواهی می‌توانید ایجاد کنید. توصیه می‌شود از نام cron-jobs استفاده کنید تا با سایر سرویس‌ها هماهنگ باشد.

نمونه فایل cron-jobs:

cron-jobs
* * * * * echo "The Docker cronjob ran at $(date)" >> /cron.log 2>&1

توجه

دقت کنید که در انتهای فایل cron-jobs باید یک خط خالی (newline) قرار داشته باشد. همچنین از فرمت خطوط Unix (LF) استفاده کنید، نه Windows (CRLF).

تنظیم Dockerfile

فرض کنید که این Dockerfile فعلی سرویس است:

Dockerfile
FROM eclipse-temurin:25
WORKDIR /app
COPY App.java .
CMD ["java", "App.java"]

برای فعال‌سازی فایل cron-jobs می‌بایست Dockerfile سرویس را تغییر دهیم:

Dockerfile
FROM eclipse-temurin:25
WORKDIR /app
COPY App.java .

#در این قسمت ابزارهای مربوط به کرون را نصب می‌کنیم
RUN apt-get update && \
apt-get install -y --no-install-recommends \
cron \
tzdata \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# برای عملکرد صحیح کرون، منطقه زمانی درست را تنظیم می‌کنیم
ENV TZ=Asia/Tehran
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# فایل کرون را به داخل ایمیج کپی می‌کنیم و به سرویس کرون معرفی می‌کنیم
COPY ./cron-jobs /cron-jobs
RUN crontab /cron-jobs

# این قسمت در ادامه توضیح داده می‌شود
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
منطقه زمانی (Timezone)

کرون از زمان کانتینر پیروی می‌کند. با تنظیم صحیح متغیر TZ می‌توانید منطقه زمانی را مشخص کنید.

اگر دقت کرده باشید، انتهای Dockerfile از این حالت:

CMD ["java", "App.java"]

به این شکل تغییر کرده است:

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

در این مثال ما فایلی به نام entrypoint.sh ساختیم و اجرای برنامه‌ی اصلی و cron را در داخل این فایل مشخص کردیم.

این فایل در مسیر اصلی سرویس قرار داده شد:

entrypoint.sh
#!/bin/bash
# اجرا سرویس کرون
cron
# اجرای برنامه‌ی اصلی
exec java App.java

ساختار و فرمت فایل Cron-Jobs

هر خط در فایل cron-jobs نشان‌دهنده یک Job مجزا است. فرمت استاندارد هر خط به صورت زیر می‌باشد:

minute hour day_of_month month day_of_week command
فیلدمحدوده مجازتوضیح
minute0-59دقیقه‌ای که دستور اجرا شود
hour0-23ساعتی که دستور اجرا شود
day_of_month1-31روز ماه که دستور اجرا شود
month1-12ماهی که دستور اجرا شود
day_of_week0-7 (0 و 7 یکشنبه)روز هفته که دستور اجرا شود
با کمک وب‌سایت crontab.guru می‌توانید زمان دلخواه‌تان را بسازید.

کاراکترهای ویژه

کاراکترمعنیمثالتوضیح
*هر مقدار (همیشه)* * * * *هر دقیقه
,لیست مقادیر1,15,30 * * * *دقیقه‌های 1 و 15 و 30
-بازه مقادیر0 9-17 * * *هر ساعت از 9 تا 17
/گام (step)*/15 * * * *هر 15 دقیقه

رشته‌های ویژه (Special Strings)

به جای فرمت استاندارد می‌توانید از رشته‌های زیر استفاده کنید:

رشتهمعادلتوضیح
@reboot-یک بار پس از راه‌اندازی سرویس
@daily یا @midnight0 0 * * *هر روز ساعت 00:00
@hourly0 * * * *هر ساعت
@weekly0 0 * * 0هر هفته یکشنبه ساعت 00:00
@monthly0 0 1 * *هر ماه روز اول ساعت 00:00
@yearly یا @annually0 0 1 1 *هر سال اول ژانویه ساعت 00:00

افزودن چندین Cron Job

برای افزودن چندین Job، کافیست هر دستور را در یک خط جداگانه بنویسید:

cron-jobs
# پشتیبان‌گیری روزانه ساعت 2 بامداد
0 2 * * * /app/backup.sh

# پاکسازی کش هر 30 دقیقه
*/30 * * * * /app/clear-cache.sh

# ارسال ایمیل هر روز ساعت 9 صبح
0 9 * * * /app/send-emails.php

کامنت‌گذاری

برای افزودن توضیحات یا غیرفعال کردن موقت یک Job، از کاراکتر # در ابتدای خط استفاده کنید:

cron-jobs
# این Job غیرفعال شده است
# * * * * * /app/old-job.sh

0 1 * * * /app/active-job.sh

مسیرها و محیط اجرا

لاگ‌گیری و خطاها

دستورات شما باید خروجی خود را مدیریت کنند. خروجی شامل ۲ حالت است:

  • STDOUT (خروجی عادی)
  • STDERR (خروجی خطاها)

تنظیمات مسیر خروجی را باید بعد از قسمت command مشخص کنید. به این مثال‌ها توجه کنید:

cron-jobs
# ذخیره خروجی(عادی و خطا) در فایل لاگ
* * * * * /app/task.sh >> /var/log/cron-task.log 2>&1

# ذخیره خروجی عادی و خطا در فایل‌های جداگانه
* * * * * /app/task.sh >> /var/log/cron-output.log 2>> /var/log/cron-error.log

# نادیده گرفتن تمام خروجی‌ها
* * * * * /app/task.sh >> /dev/null 2>&1

مسیر مطلق در مقابل مسیر نسبی

همیشه از مسیر مطلق (absolute path) برای اجرای دستورات استفاده کنید:

cron-jobs
# درست - استفاده از مسیر مطلق
* * * * * /usr/bin/php /var/www/html/artisan schedule:run

# نادرست - مسیر نسبی ممکن است کار نکند
* * * * * php artisan schedule:run

برای یافتن مسیر مطلق یک دستور از which استفاده کنید:

در کنسول سرویس
which php    # خروجی: /usr/bin/php
which python # خروجی: /usr/bin/python3