![画像](https://habrastorage.org/files/026/37b/8a5/02637b8a591446398a7c51ec53c42800.jpg)
今日は、前のプロセスがまだ完了していない場合のプロセスの定期的な起動に関連する「不便さ」を解決するための特別なケースに注目したいと思います。 言い換えると、 symfony / consoleで実行中のプロセスをブロックします。 しかし、単一のサーバーではなく、サーバーのグループ間でブロックする必要がなければ、すべてが平凡になります。
指定: Nサーバーで実行される同じプロセス。
タスク:時間単位ごとに1つだけが開始されるようにします。
「オープンスペース」にある最も人気のあるソリューション:
- データベースをロックします。
- サードパーティアプリケーション。
- ロックファイルのネイティブ使用
それぞれの主な欠点:
データベース
- 実行されるすべてのスクリプトでデータベースへの接続が必要です。
- テーブルが必要です。
- 書き込み/削除を提供するコードが必要です。
- ロックを解除する方法でスクリプトがクラッシュするときの困難; watchDogが必要です。
- 基地自体の「落下」に伴う困難
サードパーティアプリケーション(Ubuntu用のrun-oneなど)
- すべてのプラットフォームに同じ予測可能な動作を持つ同じアプリケーションがあるわけではありません。
- 追加のものを常にインストールできるとは限りません。
- 誰もが「オンライン」をブロックする方法を知っているわけではありません
ネイティブロックファイル
- 各コマンドにはファイルが必要です。
- いくつのコマンド-ロックファイルのパスと名前を含む非常に多くの行
もちろん、最も一般的なのは3番目のオプションですが、多数のサーバーとプロセスが存在する場合、多くの不便が生じます。 それで、 シングルトン symfony /コンソールベースのコマンドを書くというアイデアを共有することにしました。 しかし、このアイデアは他のフレームワークで使用できます。
そのため、最初に放棄しなければならなかったのはflock でした 。これは、たとえばsymfonyの LockHandlerで使用されます。 複数のサーバー間でブロックすることはできません。
代わりに、小さなサービスを使用して、サーバー間で共有されるディレクトリにロックファイルを作成します。これは実質的にLockHandlerに類似していますが、「sawn out」 flockを備えています。
次に取り除くべきことは、各チームがロックを手動でチェックする必要があることです。最も重要なことは、ロックは想定した場所で終わるとは限らないためです。
これを行うには、Mediatorに似たものを使用することを提案します。標準のexecute()メソッドを実装および終了します。
これは何のためですか:
- すべてのコマンドコードはlockExecute()メソッドに含まれます。
- 起動時に呼び出されるexecute()メソッドはロックを作成し、スクリプトがクラッシュ /終了したときに解放されるロックを登録し、その後でのみlockExecute()を実行します
結果として、標準のsymfonyコマンド:
class CreateUserCommand extends Command { protected function configure() { // ... } protected function execute(InputInterface $input, OutputInterface $output) { // ... } }
次のようになります。
class CreateUserCommand extends SingletonCommand implements SingletonCommandInterface { protected function configure() { // ... } public function lockExecute(InputInterface $input, OutputInterface $output) { // ... } }
さらに多くのコードを記述する必要はありませんが、同時に、いくつのサーバーがこれを実行しようとしても、1回だけ実行されることが保証されます。 唯一の条件は、ロックファイルの共有ディレクトリです。
既製のソリューションと詳細はgithubにあります: singleton-command
UPD:当然のことながら、「ハード」スクリプトがクラッシュした場合、ロックファイルを保存できます。 したがって、「古い」ロックファイルを「監視」するデーモンを編成することをお勧めします。
ご清聴ありがとうございました!