2017-01-16 4 views
0

現在、私はSpring Webアプリケーションの背後で実行されるスケジュールされたタスクに取り組んでいます。このタスクでは、cronスケジューラを使用して毎晩真夜中に実行し、未使用のアプリケーションを自分のポータルでクリーンアップします(私のサイトでは、ユーザーが記入するアプリケーションを作成でき、30日以内にフォームにアクセスしないと、タスクはDBから削除し、必要に応じて電子メールで新しいフォームを作成するようにユーザーに通知します)。テスト環境ではすべてがうまく動作し、QAに移行する準備は整っています。負荷分散されたサーバー環境の2つの電子メールの送信をブロックする

しかし、私の次の環境では、2つの負荷分散されたサーバーを使用して要求を処理しています。これは、cronスケジューラーと私のポーリングタスクが両方のサーバーで同時に実行されるため、問題です。 DBへの読み書きは問題ではありませんが、問題はアプリケーションのユーザに通知メールを送信することにあります。ポーリングロックがなければ、2つの電子メールが生成されて送信される可能性があり、これを避けたいと思います。通常は、SQLストアドプロシージャを使用し、DBにロック用のフィールドを設定し、ポーリングコードが呼び出されるたびにset/releaseするため、ポーリングのインスタンスが1つだけ実行されます。しかし、私の新しいポーリング作業では、利用可能なフィールドがないため、私はSPRINGソリューションで作業しようとしています。しかし、私はこれがちょうど番目のインスタンスは、後に実行されるようになりますかどうかわからないんだけど、またはそれ

http://www.springframework.net/doc-latest/reference/html/threading.html

そして私は

Semaphore _pollingLock = new Semaphore(1); 
_pollingLock.aquire(); 

try { 
    //run my polling task 
} 
finally { 
    //release lock 
} 

としてそれを使用して考えていた:私は、このリソースをオンラインを発見しました2番目のインスタンスをスキップし、実行されません。あるいは、この解決策は適切ではないし、よりよい解決策がある。再び、私はSpringのJavaフレームワークを使用していますので、そこに存在するすべてのソリューションが私の最高の賭けになるでしょう。

+1

セマフォは、異なるマシン上のプロセス間ではないスレッド間で同期します。データベースとトランザクションの分離レベルによっては、ブロッキング読み取りを使用して、2番目のプロセスが最初に更新用に選択された行を読み取れないようにすることができます。 –

+0

@SergioMontoro私たちは現在このソリューションを探しています。ありがとう! – user3334871

答えて

0

過去にこのような問題を処理した2つの方法は、クラスター化されたサーバーの1つを特定のタスク(電子メールの送信やジョブの実行など)を担当するサーバーとして指定することから始まります。

1つの解決策では、プロセスを実行する1つのサーバーのサーバー名を識別するすべてのクラスター化されたサーバーにJVMパラメーターを設定します。例:-DemailSendServer = clusterMember1

別の解決策では、この指定されたサーバーの起動だけでJVMパラメータを提供しました。たとえば、-DsendEmailFromMe = true

どちらの場合でも、プロセスに小さなビットのコードを追加して、起動パラメータの値または存在に基づいてゲートすることができます。

私は、パラメータの存在がプロセスを実行するのに十分であるため、使用するのが簡単であることを発見しました。最初の解決策では、代わりに現在のサーバー名とパラメーターの値を比較する必要があります。

私はSpring Batchをあまり使っていませんが、クラスタ内の単一サーバー上でジョブを実行するようにBatchを構成する方法があると仮定します。

+0

あなたの答えをありがとう!残念ながら、この環境はサーバークラスタではなく、2つのサーバーの間で共有されるのはDBだけです。したがって、ある環境に設定されているものには、他の人が到達することができません(私はインフラストラクチャに精通しているチームメンバーと相談した上でこれを実現しました)。 – user3334871

関連する問題