免主機排程神器:cron-job.org 完整教學
在上一節我們學到了如何在本地端使用 Crontab。但如果你沒有一台 24 小時開機的伺服器,那該怎麼辦呢?
如果你已經將網站或 API 部署到了免費的 PaaS 平台(像是 Render、Heroku 或 Vercel),但這些平台可能不提供免費的「背景定時任務」功能,或者就算有,免費版也有嚴格的限制(例如:伺服器 15 分鐘沒人用就會進入休眠)。
這時候,cron-job.org 就是你的救星!
什麼是 Webhook 排程?
cron-job.org 的運作原理非常簡單。它本質上就是一台位於歐洲的伺服器,你告訴它一個 網址 (URL),以及一個 時間間隔。時間一到,這台伺服器就會去存取你指定的那個網址(就像一個隱形的使用者幫你打開瀏覽器一樣)。
只要你的網址(API)被存取了,你的後端伺服器就會開始執行你寫好的程式碼。這就是所謂的 Webhook 觸發機制。
[!TIP] 常見應用場景:防止免費伺服器休眠 (Keep-alive) 許多免費平台(如 Render)如果在 15 分鐘內沒有任何 HTTP 請求,就會把你的伺服器「關機」以節省資源。下一次有人造訪時,會需要等長達 50 秒的開機時間(冷啟動)。 我們可以利用 cron-job.org,設定每 10 分鐘自動戳一次你的網站首頁。這樣一來,你的免費伺服器就會永遠保持在「開機狀態」,不用花半毛錢就獲得付費級別的服務!
註冊與建立第一個 Cronjob
1. 註冊帳號
首先前往 cron-job.org,點選右上角的 Sign Up 註冊一個免費帳號。這是一個已經穩定營運超過十年的非營利服務,非常佛心。
2. 建立新任務 (Create Cronjob)
登入後,點選介面上的 "CREATE CRONJOB" 按鈕。
這時候你會看到幾個需要設定的欄位:
- Title (標題): 給你的任務取個名字,例如「打卡機器人保活任務」。
- URL (網址): 填入你要觸發的 API 網址,例如
https://my-fastapi-app.onrender.com/api/daily-task。 - Execution schedule (執行排程):
這裡的介面非常直覺!你可以直接用點選的方式設定頻率:
Every minute(每分鐘)Every 5 minutes(每五分鐘)User-defined(自訂):如果你選擇自訂,它的介面跟我們上一節學的 Crontab 非常像,可以讓你勾選特定月份、星期與幾點幾分。
3. 進階設定 (Advanced)
對於基礎的「保活任務」,通常填完上面那些就夠了。但如果你是要觸發一支會修改資料庫的敏感 API,你可能會需要用到進階設定:
- HTTP Method: 預設是
GET。如果你的後端 API 是設計成接收POST請求,你可以在這裡將方法改為POST。 - Headers: 為了避免網路上無聊的駭客亂戳你的排程 API 導致重複執行,你應該在這裡加上自訂的身分驗證。
例如加入一組:
- Key:
Authorization - Value:
Bearer my_super_secret_token_123
- Key:
- Request Body: 如果是 POST 請求,你還可以在這裡夾帶 JSON 資料傳送給你的後端。
4. 儲存與監控
設定完成後,點擊最下方的 CREATE,你的排程就開始運作了!
在 cron-job.org 的後台,你可以清楚地看到過去幾次執行的成功/失敗紀錄 (History)。如果你的 API 發生錯誤(回傳 500),它還會記錄下伺服器回傳的錯誤訊息,甚至可以設定當任務失敗時,自動寄信到你的信箱警告你!
實戰範例:FastAPI 端點設計
如果你要搭配 cron-job.org 使用,你的後端程式碼(以 Python FastAPI 為例)大概會長這樣:
from fastapi import FastAPI, Depends, HTTPException, Header
import os
app = FastAPI()
# 取得環境變數中的金鑰
CRON_SECRET = os.getenv("CRON_SECRET", "my_super_secret_token_123")
def verify_cron_token(authorization: str = Header(None)):
"""驗證請求是否來自 cron-job.org"""
if authorization != f"Bearer {CRON_SECRET}":
raise HTTPException(status_code=401, detail="Unauthorized Request")
return True
@app.post("/api/daily-task")
async def run_daily_task(authorized: bool = Depends(verify_cron_token)):
"""
這個 API 會被 cron-job.org 每天定時呼叫
"""
print("開始執行每日任務...")
# 在這裡寫入你要自動執行的商業邏輯
# 例如:去資料庫抓報表、發送 Line 通知、清理過期資料等
return {"status": "success", "message": "Daily task completed."}
[!IMPORTANT] 安全性至上! 如果你的 Webhook API 會「寫入資料」或「發送訊息」,絕對不要將它設計成無驗證公開。因為網路上有非常多惡意爬蟲會掃描網址,如果被掃到,你的 API 可能會被一天狂戳一萬次,導致資料庫爆炸或發送一萬封垃圾信。務必像上方範例一樣,使用 Token 進行保護。
透過 cron-job.org 搭配你的後端 API,你已經解決了 80% 的定時任務需求,而且完全沒有增加任何伺服器成本!
更多 Cron Job 範例
# 每小時執行一次
0 * * * * /usr/bin/python3 /home/user/scripts/hourly_report.py
# 每天凌晨3點執行資料庫備份
0 3 * * * /home/user/scripts/backup_db.sh
# 每週一上午9點發送週報
0 9 * * 1 /home/user/scripts/weekly_report.py
# 每月1號凌晨執行月結
0 0 1 * * /home/user/scripts/monthly_close.py
常見問題排除
如果你發現你的 Cron Job 沒有按時執行,可能的原因:
- PATH 環境變數:Cron 的 PATH 很簡潔,建議使用絕對路徑
- 權限問題:確認腳本有執行權限 (
chmod +x) - 日誌檢查:查看
/var/log/cron或syslog確認執行記錄 - 郵件通知:Cron 預設會將輸出寄給使用者,可在 crontab 中設定 MAILTO
cron-job.org:沒有伺服器也能排程
cron-job.org 是一個免費的雲端排程服務。你不需要 Linux 主機、不需要設定環境——只要填入 URL 和排程時間,它就會在指定時間打你的 URL。
使用場景
你的應用部署在 Vercel、Render 或免費主機上,你需要在特定時間觸發某個 API 端點(例如每天重置資料、發送報表)。cron-job.org 就是最簡單的解法。
功能限制
| 項目 | 免費方案 | |:----|:--------| | 排程數量 | 最多 10 個 | | 最小間隔 | 每 5 分鐘 | | 執行時間記錄 | 保留 30 天 | | 通知 | Email 通知失敗 |
下一章預告:GitHub Actions 排程
cron-job.org 只能打 URL——如果你的任務需要執行程式碼(爬蟲、資料處理),GitHub Actions 是更好的選擇。