第6章: 定期実行バッチ(Cron)と非同期処理(実践チュートリアル)
個人開発で「毎朝9時に最新データを収集して通知したい」「定期的に古いレコードをバッチ削除したい」という要件は頻出します。VPSやEC2を24時間起動し続けると月数百円〜数千円の固定費がかかりますが、Cloudflare Workersの Cron Triggers を使えば 完全無料(無料枠内) でサーバーレスバッチを運用できます。
本チュートリアルのゴール
- Cron Triggers:
wrangler.jsoncでのスケジュール構文(毎時・日次実行)- 定期実行ハンドラー(
scheduled)の実装 - 待たずにテストできるローカル
curlトリガー術
- Cloudflare Queues:
- キューの作成とプロデューサー/コンシューマー設定
- 重いAPI呼び出しや通知処理の非同期平滑化
Part 1: Cron Triggers(定期バッチ)ハンズオン
Step 1: プロジェクト設定(wrangler.jsonc)
Workersにスケジュール設定を追加します。
{ "name": "my-cron-batch", "main": "src/index.ts", "compatibility_date": "2024-09-01", "triggers": { "crons": [ // 1. 毎朝9時(JST = UTC 00:00)に実行 "0 0 * * *", // 2. 毎時0分に実行 "0 * * * *" ] }}[!NOTE] Cronの時刻は「UTC(協定世界時)」
日本時間(JST)は UTC+9 です。朝9時(JST)に実行したい場合は0 0 * * *(UTC 0時)と記述します。
Step 2: バッチ処理ハンドラーの実装
src/index.ts に scheduled イベントリスナーを記述します。
export default { // 1. 定期実行ハンドラー(Cronが発火した際に呼び出される) async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) { const triggerTime = new Date(event.scheduledTime).toISOString(); console.log(`[CRON START] トリガー時刻: ${triggerTime}, cron式: ${event.cron}`);
// 例: 外部APIから為替レートを取得してDiscord/Slackに通知する処理 try { const res = await fetch('https://open.er-api.com/v6/latest/USD'); const data: any = await res.json(); const jpyRate = data?.rates?.JPY;
console.log(`現在のUSD/JPYレート: ${jpyRate}`);
// 重い処理や外部通知は ctx.waitUntil で安全に待機 ctx.waitUntil( sendNotification(`【定期為替バッチ】現在のUSD/JPY: ${jpyRate} 円 (UTC: ${triggerTime})`) ); } catch (error) { console.error('[CRON ERROR] バッチ処理失敗:', error); } },
// 2. HTTPエンドポイント(手動トリガーやヘルスチェック用) async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { return new Response(JSON.stringify({ status: 'Batch Worker is running' }), { headers: { 'Content-Type': 'application/json' }, }); }};
async function sendNotification(message: string) { // Webhook送信ロジック(Slack / Discord / LINE) console.log('[NOTIFICATION]', message);}Step 3: ローカル環境での即時テスト検証
Cronのテストで「次の時間まで何時間も待つ」必要はありません。wrangler dev 起動中に特別なテストエンドポイントへリクエストを送ることで、即座に発火させられます。
# ローカルサーバー起動npx wrangler dev別のターミナルから以下の curl を実行します。
# 登録したCron式を指定して強制トリガーcurl "http://localhost:8787/__scheduled?cron=0+0+*+*+*"開発サーバーのターミナル出力:
[CRON START] トリガー時刻: 2026-09-21T00:00:00.000Z, cron式: 0 0 * * *現在のUSD/JPYレート: 148.5[NOTIFICATION] 【定期為替バッチ】現在のUSD/JPY: 148.5 円わずか1秒でバッチ処理の正常動作を確認できます。
Step 4: 本番デプロイ
npx wrangler deployデプロイ後、Cloudflareダッシュボードの Workers > 対象Worker > Triggers タブでも登録されたCronスケジュールが有効化されていることを確認できます。
Part 2: Cloudflare Queues(非同期キューイング)
リクエスト急増時のサーバーダウンを防ぎ、処理を順次実行したい場合に Queues を使用します。
1. キューの作成(CLI)
npx wrangler queues create email-notification-queue2. wrangler.jsonc でのキュー紐付け
{ "name": "my-queue-worker", "main": "src/index.ts", // メッセージを送信する側(Producer) "queues": { "producers": [ { "binding": "EMAIL_QUEUE", "queue": "email-notification-queue" } ], // メッセージを受信・処理する側(Consumer) "consumers": [ { "queue": "email-notification-queue", "max_batch_size": 10, "max_batch_timeout": 5 } ] }}3. メッセージ送信と受信の実装例
export default { // HTTPリクエストを受けたらキューに投げて即レスポンス async fetch(req: Request, env: Env): Promise<Response> { const payload = await req.json(); await env.EMAIL_QUEUE.send(payload); // キューへエンキュー return new Response('Queued successfully', { status: 202 }); },
// キューからバッチでメッセージを取り出して処理 async queue(batch: MessageBatch<any>, env: Env): Promise<void> { for (const message of batch.messages) { console.log('キュー受信:', message.body); // メール送信処理など message.ack(); // 正常完了通知 } }};まとめ
- Cron Triggers: 常駐サーバーゼロで定時ジョブを動かし、
__scheduledエンドポイントで爆速ローカル検証。 - Queues: 大量アクセスをキューに溜めて安全に分散処理。
次章(第7章)では、オープンソースLLM(Llama 3等)をWorkersから呼び出す Workers AI のハンズオンに進みます。
💡 用語解説コラム
[!NOTE] Cron式 (Cron Expression)
定期実行のスケジュールを「分 時 日 月 曜日」の5つのフィールドで表現する構文。CloudflareではUTC(協定世界時)を基準に判定されるため、日本時間(JST)から9時間引いて計算します。
[!NOTE] メッセージキュー (Message Queue)
リクエストを一時的に待ち行列に保存し、バックグラウンドで順番に処理する仕組み。瞬間的なアクセス集中によるサーバーダウンを防ぐ「リクエストの平滑化」に効果的です。