Đọc · 6 phút Cập nhật 30/04/2026 Cấp độ · Cơ bản

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-58h sáng từ thứ 2 đến thứ 6
0 0 1 * *0h00 ngày 1 mỗi tháng
0 23 * * 023h00 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:

Nếu fail toàn bộ retry, Zeni:

  1. Đẩy event vào DLQ để retry thủ công
  2. Gửi email cho admin workspace
  3. 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

Chi phí

Bước tiếp theo