Cron Job với Cloud Scheduler
Lập lịch chạy HTTP request, gọi API hoặc trigger cloud function theo định kỳ — hằng giờ, hằng ngày, hằng tuần. Múi giờ mặc định Asia/Ho_Chi_Minh, có retry tự động và monitoring đầy đủ.
Tạo cron job
bashcurl -X POST "https://zenicloud.io/api/v1/crons?ws=prod" \
-H "Authorization: Bearer $ZENI_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "daily_sales_report",
"schedule": "0 9 * * *",
"timezone": "Asia/Ho_Chi_Minh",
"target": {
"url": "https://app.zenicloud.io/api/jobs/sales-report",
"method": "POST",
"headers": {"X-Job-Token": "secret_xyz"},
"body": {"date": "yesterday"}
},
"retry": {
"max_attempts": 3,
"backoff_seconds": 60
}
}'
Response:
json{
"cron_id": "cron_a8f3b1c2",
"name": "daily_sales_report",
"schedule": "0 9 * * *",
"timezone": "Asia/Ho_Chi_Minh",
"next_run": "2026-05-01T02:00:00Z",
"next_run_local": "2026-05-01 09:00:00 +07:00",
"status": "active"
}
Cú pháp cron
Định dạng standard 5 trường: phút giờ ngày tháng thứ
| Schedule | Ý nghĩa |
|---|---|
| 0 9 * * * | 9h00 sáng hằng ngày |
| */15 * * * * | Mỗi 15 phút |
| 0 */2 * * * | Mỗi 2 tiếng (0, 2, 4, ...) |
| 0 8 * * 1-5 | 8h sáng từ thứ 2 đến thứ 6 |
| 0 0 1 * * | 0h00 ngày 1 mỗi tháng |
| 0 23 * * 0 | 23h00 chủ nhật hằng tuần |
| 30 17 28-31 * * | 17h30 cuối tháng (28-31) |
Mẹo cron
Dùng crontab.guru để verify schedule trước khi tạo. Lưu ý: thứ tính từ 0 (Chủ Nhật) đến 6 (Thứ Bảy), KHÔNG phải 1-7.
Use cases phổ biến
Báo cáo doanh thu hằng ngày
json{
"name": "daily_revenue",
"schedule": "0 9 * * *",
"timezone": "Asia/Ho_Chi_Minh",
"target": {
"url": "https://app.example.com/api/reports/daily",
"method": "POST"
}
}
Xoá data tạm hằng đêm
json{
"name": "nightly_cleanup",
"schedule": "0 2 * * *",
"timezone": "Asia/Ho_Chi_Minh",
"target": {
"url": "https://app.example.com/api/cleanup",
"method": "DELETE",
"body": {"older_than_days": 30}
}
}
Email báo cáo cuối tháng
json{
"name": "monthly_email_summary",
"schedule": "0 8 1 * *",
"timezone": "Asia/Ho_Chi_Minh",
"target": {
"url": "https://app.example.com/api/email/monthly",
"method": "POST"
},
"retry": {"max_attempts": 5}
}
Re-index vector search hằng tuần
json{
"name": "weekly_reindex",
"schedule": "0 3 * * 0",
"timezone": "Asia/Ho_Chi_Minh",
"target": {
"url": "https://app.example.com/api/vector/reindex",
"method": "POST"
}
}
Quản lý cron qua Python
pythonimport os, requests
ZENI = "https://zenicloud.io/api/v1"
TOKEN = os.environ["ZENI_TOKEN"]
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
def create_cron(name, schedule, target_url, method="POST", body=None):
r = requests.post(
f"{ZENI}/crons?ws=prod",
headers=HEADERS,
json={
"name": name,
"schedule": schedule,
"timezone": "Asia/Ho_Chi_Minh",
"target": {
"url": target_url,
"method": method,
"body": body or {},
},
},
)
return r.json()
def list_crons():
return requests.get(f"{ZENI}/crons?ws=prod", headers=HEADERS).json()
def pause_cron(cron_id):
return requests.patch(
f"{ZENI}/crons/{cron_id}?ws=prod",
headers=HEADERS,
json={"status": "paused"},
).json()
def delete_cron(cron_id):
return requests.delete(
f"{ZENI}/crons/{cron_id}?ws=prod",
headers=HEADERS,
).status_code == 204
# Tạo job mới
job = create_cron(
"send_morning_briefing",
"0 7 * * *",
"https://app.example.com/api/briefing",
)
print(f"Cron tạo xong: {job['cron_id']}")
Retry & xử lý lỗi
Khi target URL trả về non-2xx hoặc timeout (>5 phút), cron tự động retry theo policy:
- max_attempts — số lần thử tối đa (mặc định 3)
- backoff_seconds — delay giữa các lần retry (mặc định 60s)
- Exponential backoff — Zeni nhân đôi delay sau mỗi lần fail (60 → 120 → 240)
Nếu fail toàn bộ retry, Zeni:
- Đẩy event vào DLQ để retry thủ công
- Gửi email cho admin workspace
- Log execution vào dashboard
Monitoring
Xem lịch sử chạy cron trong dashboard hoặc qua API:
bashcurl "https://zenicloud.io/api/v1/crons/cron_a8f3b1c2/history?ws=prod" \
-H "Authorization: Bearer $ZENI_TOKEN"
json{
"executions": [
{
"started_at": "2026-04-30T02:00:01Z",
"finished_at": "2026-04-30T02:00:03Z",
"status": "success",
"http_status": 200,
"duration_ms": 1840
},
{
"started_at": "2026-04-29T02:00:00Z",
"status": "failed",
"http_status": 504,
"duration_ms": 30000,
"retry_attempts": 3
}
]
}
Giới hạn
- Max 50 cron jobs per workspace (Free), 500 (Starter+)
- Schedule tối thiểu 1 phút/lần — không hỗ trợ sub-minute
- Target URL response timeout 5 phút (Cloud Run task dài hơn dùng webhook)
- Body request tối đa 1 MB
Chi phí
- Free tier — 3 cron miễn phí, không giới hạn lần chạy
- Starter+ — bao gồm trong gói, không tính riêng
Bước tiếp theo
- Webhook — chạy task dài qua queue thay vì HTTP đồng bộ
- Vector Search — re-index database định kỳ