5 phút đọcCập nhật

Cron và múi giờ: vì sao lịch chạy lệnh lệch giờ khiến đội vận hành tỉnh giấc

Tác giả: Biên tập Safe Local Tools

Cron job của bạn không “hư ngẫu nhiên”—nó chỉ chạy theo UTC trong khi bạn nhớ là giờ Hà Nội. Việc lên lịch trông tầm thường cho đến khi DST vặt một giờ, Kubernetes dùng phương ngữ cron khác Linux, và một dấu sai ở trường phút có thể khiến tác vụ dọn log chạy mỗi phút chứ không phải một lần mỗi tháng.

Hướng dẫn này tóm các trường biểu thức, bẫy múi giờ, khác biệt nền tảng, và cách dùng Safe Local Tools phân tích ngay trong trình duyệt trước khi thứ lịch đó chạm production.

Nếu bạn đã từng ngồi soi log lúc nửa đêm vì “sao hôm nay không chạy”, khả năng cao vấn đề là thời gian—không phải lệnh shell.

OG illustration

Cron trong một đoạn và vì sao không có “cron chuẩn duy nhất”

Biểu thức cổ điển có năm trường: phút, giờ, ngày trong tháng, tháng, ngày trong tuần. Một số hệ thống thêm giây (sáu trường) hoặc cả năm. Mỗi trường hỗ trợ ký hiệu * (mọi giá trị), danh sách bằng dấu phẩy, khoảng bằng dấu gạch, và bước nhảy bằng dấu gạch chéo. Điểm chính: không có một “cron vũ trụ” duy nhất. Crontab Linux, các macro có dạng @hourly, Quartz cho Java doanh nghiệp, luật của AWS EventBridge, và CronJob của Kubernetes mở rộng hoặc khóa từ vựng một cách khác nhau. Copy-paste thẳng từ tài liệu nền khác vào CronJob của bạn là nguồn gốc các sự cố không kêu.

UTC đối lập giờ địa phương: chọn và ghi nhận

Máy chủ và cluster thường chạy UTC. Người lập kế hoạch lại nhớ theo IANA zone như Asia/Ho_Chi_Minh hay Europe/Berlin. Khoảng trống đó tạo ra các hiện tượng: báo cáo “mất” một giờ khi xuân tiến, chạy trùng khi thu lùi, hoặc cảnh báo “9 giờ sáng cục bộ” lệch hai lần mỗi năm.

Khuyến nghị thực tế: cấu hình lịch và cơ sở dữ liệu nội bộ dùng UTC; khi có giao diện người dùng, hiển thị thời điểm chạy tiếp theo sau khi chuyển đổi bằng cơ sở dữ liệu múi giờ IANA. Việc thống nhất ký hiệu giúp không ai phải đoán xem YAML đang chứa “giờ tường” hay “instant thế giới”.

Trường ngày-tuần và ngày-tháng: OR hay AND không phải chuyện hiển nhiên

Một số máy chủ lịch xử lý ngày trong tuần và ngày trong tháng theo quan hệ HOẶC; nơi khác lại gần với VÀ tùy trường hợp. Khi bạn muốn “9 giờ sáng các ngày làm việc”, phải đảm bảo cả trường giờ và trường ngày trong tuần đều được diễn giải đúng và không để sót dấu * ở trường ngày—thế là cuối tuần vẫn nổ. Cách làm an toàn nhất là in ra mười lần chạy kế tiếp và đối chiếu tay với một công cụ tham khảo cùng phương ngữ.

Cạm bẫy của */5: phút hay giờ?

*/5 trong trường phút nghĩa là cứ năm phút. Trong trường giờ nó lại có nghĩa khác. Người mới hay dán */5 * * * * chờ đợi “năm giờ một lần”, rồi nhận một cơn mưa job làm máy chủ không thở nổi.

Khắc phục: trong pull request, kèm mô tả tiếng người cạnh biểu thức; reviewer nhìn thấy “mỗi phút” ngay lập tức.

CronJob Kubernetes: concurrency, deadline, suspend

Kubernetes dùng cron năm trường (không có giây). Chính sách đồng thời Forbid, Allow, Replace quyết định có cho phép hai pod dính chồng lên nhau không. Trường startingDeadlineSeconds bỏ qua lần chạy bị nhỡ sau outage—điều bất ngờ nếu bạn chờ backlog tự đuổi. Cờ suspend cho phép tắt tạm mà không xoá tài nguyên. Trước khi tin vào chiếc đồng hồ cluster, làm một lần chạy thử qua job sinh ra từ CronJob.

AWS EventBridge: rate và cron cùng tồn tại như hai ngôn ngữ khác nhau

EventBridge vừa có rate(5 minutes) vừa có biểu thức cron không giống hệt crontab cổ điển—ký hiệu dấu hỏi trong một số mẫu là đặc trưng. Runbook chỉ được phép có một họ quy tắc rõ hoặc sẽ gây nhầm lẫn trên ca trực.

Giờ tiết kiệm ánh sáng: xuân tiến và thu lùi

Khi kim đồng hồ nhảy tới, một số thời điểm địa phương không tồn tại; bạn cần chính sách từ chối hay dời. Khi kim lùi, một giờ lặp lại—job có thể kích hoạt hai lần nếu bạn không khử trùng bằng id thực thi. Lưu trữ UTC nội bộ vẫn là cách chống lệch pha rẻ nhất.

Giám sát im lặng nguy hiểm hơn tiếng ồn

Hãy log last_success_timestamp, thời lượng chạy, và cảnh báo nếu không thành công sau khoảng gấp đôi chu kỳ kỳ vọng. Cron im lặng làm pipeline dữ liệu hỏng mà không kêu—tệ hơn cả email spam từ scheduler.

Kiểm tra cục bộ trước khi triển khai

Quy trình gợi ý: (1) phân tích bằng đúng phương ngữ production, (2) in mười lần chạy kế tiếp ở UTC và ở múi kinh doanh, (3) đối chiếu với công cụ tham chiếu phù hợp phương ngữ, (4) chạy lệnh thật ở chế độ không tác động phụ. Safe Local Tools chạy phía client nên bạn có thể thử lịch nội bộ mà không phải dán tên job nhạy cảm lên trang công cộng.

Cron là thực thi mã theo thời gian—bảo vệ ai được phép sửa CronJob, bí mật gắn vào pod, và lưu lượng ra ngoài của worker lô. Khi nhu cầu vượt “ngày làm việc cuối tháng”, hãy thừa nhận cron không đủ và dùng thư viện lịch hay hàm serverless thay vì ép biểu thức bất khả thi.

Cron là thời gian chính trị chứ không chỉ là số học đẹp. Ghi nhận timezone, dialect, DST, và các chính sách overlap của orchestrator làm giảm bất ngờ. Hãy dùng một vòng kiểm tra cục bộ trước khi merge: khi các lần chạy kế tiếp hiển thị nhất quán trong UTC và múi đội của bạn, giấc ngủ của nhóm DevOps rẻ hơn nhiều so với việc mở ticket lúc nửa đêm.