2011-12-22 6 views
0

ユーザーリクエストを受け取り、それらをMYSQLデータベースに入れるWebアプリケーションがあります。これで、一般的なユーザー要求は、完了までにかなりの時間がかかるワークフローに従って処理する必要があります。これに対処するために、私は、MySQLのテーブルを聞いている非同期プロセッサを持っています。Javaでの非同期プロセスのトリガー

無限ループでMYSQLテーブルをポーリングすると、アプリケーションが配備されているボックスのCPU使用率が高くなるため、そのボックスが使用できなくなることがよくあります。

私は、MYSQLデータベースにアクティブなリクエストがないときはいつでも、 'some' timeのために非同期プロセスをスリープさせることがオプションであることを知っていますが、私は最後の手段としてそれを保持したいと思います。

単一の要求の処理に伴うワークフローの時間がかかるため、またバックエンドの進化を可能にするために処理をフロントエンドから切り離す必要があるため、このプロセスを同期させることはオプションではありません。

非同期プロセスをトリガするスマートな方法があるかどうかを知りたいので、CPU使用率が急上昇するのを避け、非同期プロセッサから最適な応答時間を得ることができます。

アドバイスをいただければ幸いです。

おかげ p1ng

+1

この質問には、2つの別々のアプリケーションがあることが示唆されています。データベースに挿入されたばかりのデータを非同期に処理するマルチスレッドWebアプリケーションを使用できない理由はありますか? – Carth

+0

現実的には、フロントエンドとバックエンドは異なるアプリケーションと見なすことができます。なぜなら、私はマルチスレッド化できない理由は、各リクエストの処理に伴うワークフローが、単数でスレッド化されていないリソースを利用しており、リクエストごとにそのリソースをブロックしたくないからです。また、非同期プロセッサーはまだ進化しており、デカップリングの必要性もあります。これは、将来、外部APIコール用にこれを開く予定であるためです。 – ping

+0

CPU使用率が急上昇している理由を詳しく説明できますか?バックエンドをマルチスレッド化することを別にすれば、なぜ最初に問題があるのか​​理解せずに何ができるのか分かりません。 –

答えて

1

オプションは、データベースに要求を保存し、あなたのシステム内のイベントのいくつかの種類を送ることであろう(例えばJMSメッセージ、またはjava.util.concurrentの構文を使用して)。コマンドを読み込んで実行するプロセスは、このシグナルによって目を覚まし、データベース内のデータを取り出して通常どおりに処理します。

このようにして、CPUサイクルがまだ使用できないデータをポーリングするのを無駄にすることはなく、ポーリングの遅延がないため、反応がさらに強くなります。

+0

ありがとう、JMSは、私が取る予定のパスです。 – ping

1

非同期プロセスをTCPソケットなどから読み取ることができます。非同期プロセスは、I/Oのブロックを待つだけです。その後、プライマリプロセスから、テーブルを更新した後、非同期プロセスにメッセージを送信することができます。データベース内のトリガからメッセージを送信することも可能です。

+0

これは興味深いです。トリガーからメッセージをどのように送信しますか?あなたは例やリンクを持っていますか? – perissf

+0

@perissfリンクをたどると、http://dev.mysql.com/doc/refman/5.0/en/faqs-triggers.html#qandaitem-B-5-1-10 –

1

私は一般に、テーブルをチェックするためにポーリングベースのアプローチをお勧めしません。異なるスケジュールで異なるイベントをポーリングする必要がある場合はどうなりますか?将来的に複数のイベントが必要な場合は、非同期タスクのメッセージキューを調べることをお勧めします。

しかし、今のところポーリングベースのアプローチをしなければならないのですが、非同期プロセスをしばらく眠らせないようにあなたの推論を完全に理解していませんか?なぜあなたのプロセスは無限ループで動作しているだけで何もしないすべてのCPUリソースを消費したいのですか?特定の間隔で非同期処理を実行するのはなぜですか?このポーリング間隔を設定可能にすることができます。

1

Java APIを使用すると、FutureTask Java APIを使用できます。 that blog entryを参照してください。

またはおそらくちょうどnew Thread(YourRunnable).start()を入力し、YourRunnableに状態変数を設定して、タスクが終了したかどうかを確認します。

関連する問題