cron-scheduling について
Node.js、Java、Python で cron による定期処理を実装する開発者向けのリファレンスです。式の例に加え、ロック、エラー処理、タイムゾーン、監視の運用上の注意点をまとめています。
主な機能
- 01Cron 式の構文と例
- 02Node.js、Java、Python の例
- 03複数インスタンス向け分散ロックの提案
- 04エラー処理と実行監視の提案
活用シーン
- 01サービスの定期クリーンアップ設定
- 02複数インスタンスでの重複実行防止
- 03遅延または失敗した定期処理の調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill cron-schedulingインストール後、Claude Code で/cron-schedulingを入力して読み込まれたか確認します。
詳細
Cron スケジューリング
Cron 式の構文
┌─────── minute (0-59)
│ ┌────── hour (0-23)
│ │ ┌───── day of month (1-31)
│ │ │ ┌──── month (1-12)
│ │ │ │ ┌─── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *
| 式 | スケジュール |
|---|---|
0 * * * * | 毎時 |
*/15 * * * * | 15 分ごと |
0 9 * * 1-5 | 平日の午前 9 時 |
0 0 1 * * | 毎月 1 日の午前 0 時 |
0 */6 * * * | 6 時間ごと |
Node.js(node-cron)
import cron from 'node-cron';
// Run every day at 2:00 AM
cron.schedule('0 2 * * *', async () => {
console.log('Running daily cleanup...');
await cleanupExpiredSessions();
}, {
timezone: 'America/New_York',
});
// Run every 5 minutes
cron.schedule('*/5 * * * *', async () => {
await syncExternalData();
});
分散ロックを使用する場合(二重実行を防止)
import { Redlock } from 'redlock';
const redlock = new Redlock([redis]);
cron.schedule('0 * * * *', async () => {
let lock;
try {
lock = await redlock.acquire(['cron:hourly-report'], 60000);
await generateHourlyReport();
} catch (err) {
if (err instanceof Redlock.LockError) return; // Another instance has the lock
throw err;
} finally {
await lock?.release();
}
});
Spring @Scheduled(Java)
@Component
@EnableScheduling
public class ScheduledTasks {
@Scheduled(cron = "0 0 2 * * *") // Daily at 2 AM
public void dailyCleanup() {
sessionRepo.deleteExpired();
}
@Scheduled(fixedRate = 300000) // Every 5 minutes
public void syncData() {
externalService.sync();
}
@Scheduled(fixedDelay = 60000) // 60s after last completion
public void processQueue() {
queueService.processNext();
}
}
分散スケジューリング(ShedLock)
@Scheduled(cron = "0 */10 * * * *")
@SchedulerLock(name = "syncInventory", lockAtLeastFor = "5m", lockAtMostFor = "10m")
public void syncInventory() {
inventoryService.syncAll();
}
Python(APScheduler)
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
scheduler = AsyncIOScheduler()
@scheduler.scheduled_job(CronTrigger(hour=2, minute=0))
async def daily_cleanup():
await cleanup_expired_sessions()
@scheduler.scheduled_job('interval', minutes=5)
async def sync_data():
await sync_external_data()
scheduler.start()
アンチパターン
| アンチパターン | 対策 |
|---|---|
| ロックなしで複数インスタンス上で Cron を実行する | 分散ロック(Redlock、ShedLock)を使用する |
| 実行時間の長い Cron が次の実行を妨げる | 負荷の高い処理にはジョブキューを使用する |
| Cron のエラーハンドリングがない | try-catch で囲み、エラーをログに記録して通知する |
| スケジュールをハードコードする | 環境変数または設定を使用する |
| Cron の実行を監視していない | 開始時刻と終了時刻をログに記録し、失敗を追跡する |
本番環境チェックリスト
- 複数インスタンスのデプロイで分散ロックを使用する
- 通知機能を備えたエラーハンドリング
- 実行時間の監視
- タイムゾーンを明示的に設定する
- グレースフルシャットダウン(現在のジョブを完了する)
- Cron 式を文書化する
コメント
Markdown 対応