- PR -

Servletでバッチ処理のような時間のかかる処理について

投稿者投稿内容
raystar
ぬし
会議室デビュー日: 2003/01/16
投稿数: 251
お住まい・勤務地: Tokyo/Japan
投稿日時: 2003-12-14 15:17
こんにちは。

例えば、CSVファイルに約1000人分のユーザデータがあるとします。
それをアップロードし、DBにインサートし、
クライアントにメッセージを返します。

1000人分のユーザデータをServletで処理をした場合、
次の画面(JSP)に遷移するまで非常に時間がかかってしまいます。

そこで、Servletにて1000人分のユーザデータをセッションに格納し、
URLConnectionなどで別のサーブレットに処理を委譲して、
すぐさまJSPにforwardし、結果をログに書き、
ユーザには「処理を実行しました。結果はログに保存します。」
という流れを組みたいと思っております。

つまり、登録処理を完全にバックグラウンドで行いたいということなのです。

この場合、別サーブレットにDB処理を行わせている間、
レスポンスを待たずに、次の処理を行わせるには
どのようなテクニックを使うのが最適でしょうか。

皆様の意見をお聞かせください。

URL url = new URL("http://127.0.0.1/AddUser");
URLConnection urlConn = url.openConnection();

urlConn.setDoOutput(true);

// ここで待ちたくないのです。
urlConn.getInputStream();
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-12-14 15:38
サーブレットにバックグラウンド処理をさせるより、
バッチプログラムを作成して、それを起動させた方が簡単だと思います。

以下の流れで。
1.アップロードファイルを保存
2.バックグラウンドでバッチ処理(1のファイルを使用)を起動
3.クライアントにメッセージを返す


[ メッセージ編集済み 編集者: ぽん 編集日時 2003-12-15 12:50 ]
raystar
ぬし
会議室デビュー日: 2003/01/16
投稿数: 251
お住まい・勤務地: Tokyo/Japan
投稿日時: 2003-12-14 15:54
引用:

2.バックグラウンドでバッチ処理(@のファイルを使用)を起動



ぽんさん、レスありがとうございます。
Runtime#exec() メソッドの終了を待たずにJSPにフォワードしてしまえばいいわけですね。

確かにサーブレットを使った場合ですと、
タイムアウトなど色んな問題が出てきそうですし・・・
teto
ベテラン
会議室デビュー日: 2002/07/31
投稿数: 61
投稿日時: 2003-12-14 22:14
はじめまして

>2.バックグラウンドでバッチ処理(@のファイルを使用)を起動

ですが、サーブレットとは別プロセスで起動されるのは
なにか気持ち悪い気がします。

単純に、スレッドを起こしてそこで処理させれば?とか
おもってしまうのですが、どうでしょう?

私自身、こういったケースは運良く(?)実装したことが
ないので、はっきり言えないのですが。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2003-12-14 23:08
raystarさん、そして皆さんこんにちは。

このシステムが単一ユーザからしかアクセスされないのなら、
サーブレットから別スレッドを起こす方法でも、別プロセスによる
バッチ処理でもあまり問題ないように思います。
(CSVファイルを使うようですからそうなのでしょうね)

しかし、複数ユーザがアクセスするなら、どちらの方法をとるにせ
よ、ちゃんとDB、トランザクションの設計する必要があると思います。
バッチ処理中のレコードを別のユーザが同時に更新するのは怖いことです
し、長時間排他掛けられると次の人がイライラすることになります。

あと、私も
引用:
Runtime#exec() メソッドの終了を待たずにJSPにフォワード
してしまえばいいわけですね。


と思いますが、サブプロセスが吐き出す標準出力、標準エラー出力の内容
をちゃんと吸い出してあげないと、サブプロセスが正常終了できない場合が
あるので注意が必要です。
また、適切にリソースを解放させるためにはサブプロセスはちゃんと
waitFor()してあげたほうが良いと思います。
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2003-12-15 11:39
引用:

raystarさんの書き込み (2003-12-14 15:17) より:

つまり、登録処理を完全にバックグラウンドで行いたいということなのです。

この場合、別サーブレットにDB処理を行わせている間、
レスポンスを待たずに、次の処理を行わせるには
どのようなテクニックを使うのが最適でしょうか。



EJBが使用可能ならメッセージドリブンBeanというのはいかがでしょう?
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-15 12:11
引用:

EJBが使用可能ならメッセージドリブンBeanというのはいかがでしょう?


この程度の要件のためにメッセージキューを使うのはオーバースペックな気が
しますが、方法としてはアリですよね。

私なら、別スレッド立ててそこでバッチのロジックを実行するか、そこから
更にSystem#execしてバッチを起動するか、ですねえ。ただ、かなり時間の
かかる処理のようですし、コンテナと同一JVM内でバッチのロジックを起動する
のはちょっと嫌な感じです。コンテナのサービスに影響をあまり与えないように
するために、System#execするのが良いような気がします。

ちょっとうまい例が思い浮かびませんが、別プロセスにすることで監視ツールを
使い易くなったりしませんかね?バッチが途中でハングアップするような
シチュエーションでも、監視ツールで例えば「このバッチの実行は通常は1時間
掛かるので、3時間以上経ってもまだプロセスが生きているのはおかしい」とか
いった感じで。


[ メッセージ編集済み 編集者: おばけ 編集日時 2003-12-15 12:22 ]
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2003-12-15 12:35
私もせっかく JBoss を使っているのなら MDB を使ってみては?と思います。
↓みたいに、スレッドを起こしてみてもいいと思いますが。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=7110&forum=12

>使い易くなったりしませんかね?バッチが途中でハングアップするような
>シチュエーションでも、監視ツールで例えば「このバッチの実行は通常は1時間
>掛かるので、3時間以上経ってもまだプロセスが生きているのはおかしい」とか
WebLogic なんかだと、特定のスレッドが指定した時間以上同じ処理に占有されていると警告ログが出力されます。JBoss にもありませんかね・・・?

スキルアップ/キャリアアップ(JOB@IT)