2016-10-11 13 views
0

誰でも。私は確かに可能ではないと確信していますが、私はとにかく尋ねると思っていました。クラスを宣言しないで、メモリからダンプしてください。

これは名前空間やクラスの再定義とは関係ありません。私はその状況を説明しなければならない。

私はPHPベースのCLIワーカーを持つRabbitMqキューイングシステムを持っています。これらの労働者は数時間持続しています。少し黒いPHPの心臓部には、工場や流通パターンがあり、さまざまなタスクを実行することができます。各タスクは別個のクラスであり、ワーカーは単に待ち行列とメッセージストリームに接続する手段である。

ここで、これらのさまざまなタスクの1つでコードを二つ折りにする必要があるときがあります。それらが永続的であるため、以前のクラス定義をアンロードするためには、ワーカーを強制終了する必要があります。

このシステムの各ワーカーには、さまざまなコマンドを送信できるコマンドキューがあります。このキューに自分自身を登録し、そのキューから登録抹消されたもの、dieなどなどは基本的にそれぞれのジョブは独自の動的キューを作成するので、このコマンドチャネルを使用してキュー/ジョブを選択する必要があります。

私が今言ったように、すべての作業を停止する必要がある場合は、それらを終了する必要がある場合、それらが死ぬのを待って、再起動します。

メモリからこれらのクラス定義をダンプすることができれば、はるかにエレガントな状況になり、必要なときに新しいコードでリロードすることができます。

私の人生にとって、私はそれをする方法を理解できません。

いずれのアイデアも高く評価されます。

答えて

0

これはかなり広いトピックですが、私はそれを試してみましょう。

ダウンタイムを最小限に抑えることができます。私はあなたがCLIのプロセスを再起動するために行くつもりだが、のツイストでクラスをアンロードできるとは思わない。

IISには、application recycleという同様のメカニックがあります。それはあなたの場合にアファインかもしれないし、そうでないかもしれません。私はあなたの特定のケースのためにそれを実装する方法を説明します。次のように

PHP CLIアプリが行う必要があります(後でそのことについて)コンパートメント内

  • 実行を。
  • リスナーのポート番号をコマンドラインから受け入れます。
  • リッスンしているUNIXソケットからのコマンドを受け入れます。
  • は、ドレインコマンドを持っています。

コンパートメント

あなたは、同時にそのプロセスの各同じプログラムの複数のインスタンスを実行して想像してみてください。どんな静的リソースも偽装されるでしょう。これを避けるには、区画は、インスタンスを他のすべてのインスタンスから隔離します。例としては、Unixソケット、TCP/IPソケット、書き込み可能なファイル(読み取り専用ファイルではない)、一時ファイルとフォルダ、コンソール、データベース上のクリティカルセクションなどがあります。

インスタンスの干渉を避けるには、これらのすべてのコリジョンポイントを何とか処理する必要があります。例えば、dump.datのような静的なファイル名の代わりにdump-<pid>.datまたは.../<pid>/dump.datを使用し、BEGIN TRANSACTION..COMMITでSQLクエリを修正し、他のファイルと同様にUNIXソケットをオープンする(PID(プロセスID) socket-<pid>.io)とユニークなポートを備えたTCP/IPソケット。

プログラムは、その区画内で実行することができたら、同時に実行複数のインスタンスを妨げるものは何もありません。

リスナーのポート番号

は、あなたがプログラムを実行することができると言いますa --port=<port>オプション。これにより、jusを設定することはできませんプログラムではなく、単一のインスタンス(プログラムの1回の実行)。これは、RabbitMQからそのポートにメッセージをリダイレクトする必要があるため必要です。

すべてのメッセージを複数のコンシューマに送信し、コンシューマがオフラインのときに特定のポリシーを適用するようにRabbitMQを設定できます。たとえば、ポート40000とポート40010にメッセージを送信し、配信されていないメッセージを遅延処理用にキャッシュする必要があります。これで、RabbitMQ設定に再び触れることなく、2つのポートで待機中の2つのインスタンスを実行し、1つのインスタンスをシャットダウンするか、または両方をシャットダウンすることができます。

UNIXソケットコマンド

PHPアプリケーションは、UNIXソケットを開き、コマンドをリッスンします。コマンドラインからは簡単にpipe text into the UNIX socketとすることができます。たとえば、drain文字列(コマンド)を送ることができます。

ドレインコマンド

プログラムがdrainコマンドを受信すると、最後のメッセージが処理された後、アプリは、MQ、プロセスから残りのすべてのメッセージを任意の複数のメッセージを受け付けなくなりますが、シャットダウンします。私はISSのdrain stop commandからこの考えを得ました。あなただけの(プロセスのPIDを確認してください)シャットダウンにそれを待つ、最初のインスタンスへdrainコマンドを送信し、最初にシャットダウンせずに新しいインスタンスを実行することができます。この時点で、ノード

をリサイクルする

手順。一方、新しいインスタンスは100%の稼働時間で他のポートでメッセージを実行して処理します。時が来たら、これらのステップを繰り返しますが、逆の役割(グラフィックスカードがダブルバッファリングを行う方法と非常に似ています)を繰り返します。

このアイデアについての最も良いこと

...これはアーキテクチャ上の選択です。アプリケーション設計の問題だけではありません。すべてのケースを処理するには、ソースコードに再度触れることなくインスタンスを設定します。この再構成は、RabbitMQの同じ設定パターンをスケールアップしてそれに従う場合に重要です。組織内のサービス・マネージャーはMQとノードを再構成することができます(たとえば、2つの異なるマシンに2つのインスタンスを分散させるか、またはそれらを同じマシンに保持するなど)。

もう1つの良い点は、1台のマシンで実行されている場合は、すべてのスクリプトを作成できることです。シンプルなシェルスクリプトを使用すると、インスタンスのリサイクルを実行できます。

cronジョブを使用する場合は、インスタンスの正常性(メモリフットプリントまたはその他のメトリック、応答時間を測定するのに最適です)とインスタンスが古くなった場合でも、リサイクルスクリプトを実行できます。

もう1つ良いことは、これがすべて増分であることです。コンパートメントを実装してから、UNIXソケットを実装して手動で使用することができます。あなたの動きに自信があるときは、スクリプトを作成してスクリプトを自動化することができます。そして、これが些細な日々の練習になったときには、それの上にcronの仕事を入れてください。

私はこれが長いポストのために意味があり、申し訳ありません。

+0

いいえ、非常に興味深いです。私は実際に私たちの現在のシステムを再構築しています。どちらがうまくいくのですが、RabbitMqでの最初の試みでした。これは、私がボードに来る前に構築されたプロセス状態のDBを使った古いシステムの変換です。現在のものは約2歳ですので、私はそれをいくつかのtweeksを再加工したいと思いました。 – ArtisticPhoenix

+0

私は細部まであなたを退屈させることはありませんが、私は考えてくれました。基本的には、私が記事で述べたようにコマンドキューの設定をしています。コマンドを送信する専用のキューがあるのは、他のキューがジョブごとにジョブごとに作成されるため、ジョブはほとんど実行されませんが、それらは数百万の検索で非常に大規模です。ですから、基本的には、行を取り出して一度にいくつかのプロセスにフィードして、レポートを作成し直してレポートを作成するというものです。レポートは単一の作業者とは別のステップです。 – ArtisticPhoenix

+0

あなたのドレインの例を使用すると、プロセスにKillコマンドを送信してからレジスタコマンドを送信するだけで、killコマンドを取得すると現在のプロセスが終了し、始まる。 – ArtisticPhoenix

関連する問題