عبارت cron چیست؟
یک عبارت cron یک رشته زمانبندی فشرده است که به یک scheduler job دقیقاً میگوید چه وقت یک task را اجرا کند. این فرمت در ۱۹۷۵ در daemon یونیکس V7 cron متولد شد و از آن زمان تقریباً تغییری نکرده است — همان گرامر پنجفیلدی امروز در Kubernetes CronJob، AWS EventBridge، GitHub Actions، Google Cloud Scheduler، GitLab CI، Jenkins pipeline ها و باینری crontab که همچنان با هر توزیع لینوکس ارائه میشود دیده میشود. گرامر معنای زیادی را در حدود سیزده کاراکتر جای میدهد، به همین دلیل تجزیهگری که آن را به متن ساده تبدیل میکند تفاوت بین یک deploy مطمئن و یک rollback ساعت ۳ شب است.
عبارت cron چگونه کار میکند؟
یک عبارت cron استاندارد پنج فیلد جدا شده با فاصله دارد که با هم یک برنامه تکراری تعریف میکنند. موتور هر دقیقه ساعت دیواری فعلی را با عبارت مقایسه میکند و job را وقتی هر پنج فیلد مطابقت دارند اجرا میکند. فیلدها، از چپ به راست:
- دقیقه (۰-۵۹). کدام دقیقه در ساعت job اجرا میشود.
0یعنی سر ساعت،30یعنی نیم ساعت بعد،*/5یعنی هر پنج دقیقه (۰۰، ۰۵، ۱۰، ...)، و15,45یعنی ربع بعد از و ربع مانده به. - ساعت (۰-۲۳). کدام ساعت از روز بر اساس ساعت ۲۴ ساعته.
0نیمه شب است،9ساعت ۹ صبح است،17ساعت ۵ بعد از ظهر. بازهها (9-17برای ساعتهای کاری) و مقادیر گام (*/2برای هر ساعت یک در میان) مانند دقیقه عمل میکنند. - روز ماه (۱-۳۱). کدام روز تقویمی اجرا شود.
1یعنی اول ماه،*یعنی هر روز،1,15یعنی اول و پانزدهم. مراقب31باشید — ماههایی که روز ۳۱ ندارند به آرامی از دست میروند. - ماه (۱-۱۲ یا JAN-DEC). کدام ماهها اجرا شوند.
*یعنی هر ماه،1,7یعنی ژانویه و جولای،1-3یعنی فقط سهماهه اول. نامهای سهحرفی ماه در اکثر پیادهسازیها به حالت حروف حساس نیستند. - روز هفته (۰-۷، جایی که هم ۰ و هم ۷ یعنی یکشنبه). اجرا را به روزهای هفته خاص محدود میکند.
1-5دوشنبه تا جمعه است،0,6آخر هفته است،MON-FRIدر اکثر تجزیهگرها کار میکند. وقتی هم روز ماه و هم روز هفته مقادیر خاصی دارند، cron کلاسیک در هر مطابقت (OR منطقی) اجرا میکند، که هر بار مردم را متعجب میکند.
چرا از تجزیهگر cron استفاده کنیم؟
- قبل از deploy، خواندن اشتباه خاموش را شناسایی کنید. عبارت `0 2 */3 * *` در ساعت ۲ بامداد هر سه روز اجرا میشود، نه هر سه دقیقه — آن را اینجا پیست کنید و قبل از ارسال به production آن را به متن ساده میبینید.
- اکثر scheduler های ابری به طور پیشفرض در UTC اجرا میشوند. پیشنمایش ۱۰ زمان اجرای بعدی در منطقه زمانی محلی شما، انحراف DST یک ساعته را قبل از اینکه کسی را ساعت ۳ بامداد بیدار کند نشان میدهد.
- میانبرهایی مثل `@daily`، `@weekly` و `@monthly` مناسب اما مبهم هستند. تجزیهگر فرم پنجفیلدی زیرین را نشان میدهد تا دقیقاً بدانید چه چیزی schedule شده.
- سازنده فیلد به فیلد به شما اجازه میدهد یک برنامه را ستون به ستون ترکیب کنید و توضیح بهروز شده را live ببینید، که بسیار سریعتر از خواندن مجدد صفحه man cron برای دهمین بار است.
عبارات cron کجا استفاده میشوند؟
سینتکس cron در هر جایی که یک job نیاز به تکرار بر اساس ساعت دارد نمود پیدا میکند. سه سطح رایجتر، با مشکل دقیقی که هر کدام برای آن معروفاند:
- برنامههای backup. ورودی کلاسیک `crontab -e` که یک پایگاه داده را هر شب ساعت ۲ بامداد به S3 export میکند، یا یک آرشیو `pg_dump` را در اول هر ماه میچرخاند. یک خط مثل `0 2 * * * /usr/local/bin/backup.sh` روی بیشتر سرورهای لینوکس از هر خط cron دیگری وجود دارد.
- trigger های `schedule` در GitHub Actions. کلید `on.schedule.cron` در `.github/workflows/*.yml` cron استاندارد پنجفیلدی میپذیرد، اما job همیشه در UTC اجرا میشود و GitHub به آرامی یک زمان اجرا را skip میکند اگر صف runner شلوغ باشد. پیشنمایش در منطقه زمانی محلی قبل از commit کمک میکند.
- AWS EventBridge Scheduler. عبارات cron EventBridge یک فیلد ششم برای سال دارند و به جای
*در یکی از فیلدهای روز?میخواهند — `cron(0 9 ? * MON-FRI *)` ترجمه EventBridge از cron هفتههای کاری ۹ صبح استاندارد است. عدم تطابق با سینتکس cron کلاسیک منبع اصلی خطاهای `ValidationException` در deploy های CloudFormation است.
یک عبارت cron واقعی چگونه است؟
عبارت 0 9 * * 1-5 را در نظر بگیرید — هر روز کاری ساعت ۹:۰۰ صبح اجرا میشود. خواندن فیلدها از چپ به راست: 0 دقیقه صفر ساعت است، 9 ساعت ۹ صبح در ساعت ۲۴ ساعته است، * در روز ماه یعنی هر روز تقویمی، * در ماه یعنی هر ماه، و 1-5 در روز هفته اجرا را به دوشنبه تا جمعه (جایی که ۱ = دوشنبه) محدود میکند. آن را در ورودی بالا پیست کنید و تجزیهگر تأیید میکند ساعت ۰۹:۰۰، دوشنبه تا جمعه با ۱۰ تاریخ اجرای بعدی در هر منطقه زمانی IANA که انتخاب میکنید. همان هدف در سینتکس AWS EventBridge cron(0 9 ? * MON-FRI *) است — فیلد سال در انتها و ? جایی که cron استاندارد * استفاده میکند توجه داشته باشید. همان هدف به عنوان یک عبارت Quartz (ششفیلدی با ثانیههای پیشرو) 0 0 9 ? * MON-FRI است. سه پلتفرم مختلف، سه شکل سطح مختلف، یک برنامه زمانی زیرین.
عبارات cron دقیقاً به یک روش بیرحم هستند: یک اشتباه تایپی یک برنامه زمانی معتبر از نظر نحوی ایجاد میکند که در زمان اشتباه اجرا میشود، بدون هیچ خطایی که در code review قابل تشخیص باشد. خواندن `0 0 1 * *` و دانستن اینکه هر ماه اول در نیمه شب اجرا میشود، نه ۱ ژانویه، نیاز به تمرین دارد. تجزیهگر بالا آن تمرین را به یک بررسی ده ثانیهای تبدیل میکند — عبارت را پیست کنید، انگلیسی را بخوانید، ۱۰ زمان اجرای بعدی را در منطقه زمانی محلی خود بررسی کنید، و YAML را با این اطمینان که خط cron واقعاً آنچه پیام commit میگوید انجام میدهد، ارسال کنید.
تفاوت بین cron پنجفیلدی و ششفیلدی چیست؟
cron پنجفیلدی گرامر کلاسیک یونیکس با وضوح یک دقیقه است. cron ششفیلدی یک ستون ثانیه پیشرو برای زمانبندی زیر دقیقه اضافه میکند — توسط Quartz و @Scheduled اسپرینگ استفاده میشود. AWS EventBridge نیز شش فیلد استفاده میکند، اما ستون اضافی آن سال پسرو است نه ثانیه.
معنی @hourly، @daily و @weekly چیست؟
ناممستعارهای Vixie-cron که در ۱۹۸۷ معرفی شدند. @hourly = 0 * * * *، @daily = 0 0 * * *، @weekly = 0 0 * * 0، @monthly = 0 0 1 * *، @yearly = 0 0 1 1 *. @reboot یک بار در هنگام boot اجرا میشود. GitHub Actions و EventBridge این alias ها را رد میکنند.
در cron، یکشنبه روز ۰ است یا روز ۷؟
هر دو، در cron کلاسیک Vixie — 0 و 7 هر دو پذیرفته میشوند تا بازههایی مثل 5-7 به طور طبیعی به عنوان جمعه تا یکشنبه خوانده شوند. دوشنبه همیشه 1 است، شنبه همیشه 6 است. Quartz و AWS EventBridge از قرارداد متفاوتی استفاده میکنند: 1-7 با یکشنبه به عنوان 1. قبل از فرض کردن، مستندات پلتفرم را بررسی کنید.
cron با وقت تابستانی (DST) چگونه کنار میآید؟
بستگی به منطقه زمانی موتور دارد. در UTC (پیشفرض در EventBridge، Kubernetes و GitHub Actions) DST وجود ندارد. در یک منطقه DST محلی، cron Vixie کلاسیک job هایی را که در فاصله spring-forward هستند skip میکند و در طول fall-back دو بار اجرا میکند؛ تایمرهای systemd دقیقاً یک بار اجرا میکنند.