DEV Community 日本語 フォロー Symfonyスケジューラーコンポーネント:アプリ内のCron、Crontabではない この記事では、PHPアプリケーションにおけるスケジュール済みタスクの管理において、従来のcrontabに代わるモダンな選択肢としてSymfony Schedulerコンポーネントについて論じています。crontabの、ホスト固有である、バージョン管理の外にある、管理やテストが難しいといった問題点を強調しています。Symfony Schedulerは、繰り返しタスクをバージョン管理されたPHPコードとして再配置し、コードレビューや単体テストを可能にします。Schedulerのコアは、#[AsSchedule]でマークされ、ScheduleProviderInterfaceを実装したスケジュールプロバイダークラスです。このクラスは、人間が読める間隔をRecurringMessage::every()で、または標準的なcron式をRecurringMessage::cron()で指定して、どのタスクをいつ実行するかを定義します。メッセージ自体はプレーンなData Transfer Objects(DTO)です。cron式の場合、dragonmantank/cron-expressionパッケージが必要であり、これは負荷を分散し、共通の時間帯での同時実行を防ぐためのハッシュ化されたcron式という機能を提供します。Schedulerは、基盤となるエンジンとしてSymfony Messengerコンポーネントに依存しており、スケジュールされたメッセージは他のアプリケーションメッセージと同じミドルウェア、リトライ戦略、および障害処理を通過します。タスクは、専用のハンドラーを持つメッセージとして定義することも、単純な単発操作のために#[AsCronTask]および#[AsPeriodicTask]属性を使用してサービスメソッド上で直接定義することもできます。Schedulerの重要な利点はテスト容易性であり、スケジュールは完全なアプリケーションを起動したり実行を待ったりすることなく単体テストできます。この記事では、クリティカルな注意点として、複数のスケジューラーコンシューマープロセスを実行するとタスクが重複実行されるという点を警告しています。これを防ぐために、Schedulerトランスポートはロックで設定する必要があり、これにより1つのプロセスのみがスケジュールされたメッセージを生成することが保証されます。このロックは、Redisのような共有ストアによってバックアップされるべきです。冗長性のために、コンシューマーは水平方向にスケールできますが、ロックを保持してスケジューリングを実行するのは1つのワーカーのみであるべきです。さらに、共有キャッシュプールを使用することでSchedulerをステートフルにすることができ、ワーカーが再起動した際に実行されなかったタスクをキャッチアップできます。最終的に、Symfony Schedulerはスケジューリングの懸念をインフラストラクチャからアプリケーションコードへと移動させ、疎結合アーキテクチャの原則に沿ったものにします。このアプローチは、スケジューリングロジックをアプリケーションのコードベース内でバージョン管理、レビュー可能、およびテスト可能に保つことで、保守性を向上させます。 The Symfony Scheduler Component: Cron in Your App, Not Your Crontab dev.to DEV Community RSS thenote.app
#[AsSchedule]でマークされ、ScheduleProviderInterfaceを実装したスケジュールプロバイダークラスです。このクラスは、人間が読める間隔をRecurringMessage::every()で、または標準的なcron式をRecurringMessage::cron()で指定して、どのタスクをいつ実行するかを定義します。メッセージ自体はプレーンなData Transfer Objects(DTO)です。cron式の場合、dragonmantank/cron-expressionパッケージが必要であり、これは負荷を分散し、共通の時間帯での同時実行を防ぐためのハッシュ化されたcron式という機能を提供します。Schedulerは、基盤となるエンジンとしてSymfony Messengerコンポーネントに依存しており、スケジュールされたメッセージは他のアプリケーションメッセージと同じミドルウェア、リトライ戦略、および障害処理を通過します。タスクは、専用のハンドラーを持つメッセージとして定義することも、単純な単発操作のために#[AsCronTask]および#[AsPeriodicTask]属性を使用してサービスメソッド上で直接定義することもできます。Schedulerの重要な利点はテスト容易性であり、スケジュールは完全なアプリケーションを起動したり実行を待ったりすることなく単体テストできます。この記事では、クリティカルな注意点として、複数のスケジューラーコンシューマープロセスを実行するとタスクが重複実行されるという点を警告しています。これを防ぐために、Schedulerトランスポートはロックで設定する必要があり、これにより1つのプロセスのみがスケジュールされたメッセージを生成することが保証されます。このロックは、Redisのような共有ストアによってバックアップされるべきです。冗長性のために、コンシューマーは水平方向にスケールできますが、ロックを保持してスケジューリングを実行するのは1つのワーカーのみであるべきです。さらに、共有キャッシュプールを使用することでSchedulerをステートフルにすることができ、ワーカーが再起動した際に実行されなかったタスクをキャッチアップできます。最終的に、Symfony Schedulerはスケジューリングの懸念をインフラストラクチャからアプリケーションコードへと移動させ、疎結合アーキテクチャの原則に沿ったものにします。このアプローチは、スケジューリングロジックをアプリケーションのコードベース内でバージョン管理、レビュー可能、およびテスト可能に保つことで、保守性を向上させます。