2011-02-05 42 views
39

誰でもアドバイスできますか?私は、ユーザーがデータマイニング要求をJava JSPとサーブレットを介してインタラクティブにアプリケーションのアプリケーションに送信し、データのアソシエーションルールを動的に処理する状況があります。TomcatでバックグラウンドJavaプログラムを実行する

このようなジョブはしばらく時間がかかる可能性があります。私はバックグラウンドでこのような要求を実行するためにサーバー上で何らかのプロセスを考えていますので、セッションをロックしたり、メモリをシステムに損害を与えます。

システムは、一連のJava JSPとサーブレットがMySQLデータベース上でTomcatコンテナ内で実行されているため、誰も手伝ってくれますか?

おかげ

氏モルガン

+0

あなたが戻って応答を与えることを期待している行うことができますか?また、Tomcatでは複数の同時リクエストを処理するために必要なときに展開できるスレッドプールを使用します。 –

+0

"データマイニング要求"の結果をユーザーに表示する(または完了したジョブを通知する)必要がありますか?そして、どうすればそれをする必要がありますか? –

+0

私は、仕事が終わったときに、結果が利用可能であると言うためにユーザーにメールを送ることができると考えていました。 –

答えて

5

私はクォーツスケジューラは、あなたがここで何をしたいのかを達成することができるはずだと思います。ここにはexamples from Quartzの一部があります。これを使用すると、着信要求を処理するために迅速にポーリングするcronを開始できます。私は実際に私のプロジェクトの1つのためにそれをしました。

+0

私は毎時スケジュールされた仕事のためにシステムのどこかでQuartzを使用しますが、それは可能性があります。 –

+3

石英は良い呼び出しです。それは "一度、今すぐジョブを実行する"非常によく行うでしょう。もう一つの利点は、再起動機能を提供することです。ジョブを開始すると、quartzは要求を「保存」し、システムがダウンした場合にジョブを再開することができます。あなたは "無料"のためにすべてのものを手に入れます。すでに持っているので、あなたはすでにそれをどのように使用するかを知っています。あなたがする必要がない場合は、なぜあなたは新しいキットをスタックに追加するのですか? –

+0

@ウィル:+1 ...よく言った。 :) – limc

48

使用ExecutorService GlassfishのかJBossのような本当のAppServerにスイッチをeigherまたは(リンクの下に)自分自身でTomcatにJMS機能を追加することがあります。

スレッドをデーモンスレッドとしてマークすると、エラーシナリオでは少なくともtomcatと結びついていないので、サーブレットコンテキストが破棄されたときにexecutorを停止する必要があります(たとえば、再デプロイ時。またはこれを行うには、あなたのアプリケーションを停止、のServletContextListener使用:

public class ExecutorContextListener implements ServletContextListener { 
    private ExecutorService executor; 

    public void contextInitialized(ServletContextEvent arg0) { 
     ServletContext context = arg0.getServletContext(); 
     int nr_executors = 1; 
     ThreadFactory daemonFactory = new DaemonThreadFactory(); 
     try { 
      nr_executors = Integer.parseInt(context.getInitParameter("nr-executors")); 
     } catch (NumberFormatException ignore) {} 

     if(nr_executors <= 1) { 
     executor = Executors.newSingleThreadExecutor(daemonFactory); 
     } else { 
     executor = Executors.newFixedThreadPool(nr_executors,daemonFactory); 
     } 
      context.setAttribute("MY_EXECUTOR", executor); 
     } 

    public void contextDestroyed(ServletContextEvent arg0) { 
     ServletContext context = arg0.getServletContext(); 
     executor.shutdownNow(); // or process/wait until all pending jobs are done 
    } 

} 
import java.util.concurrent.Executors; 
import java.util.concurrent.ThreadFactory; 

/** 
* Hands out threads from the wrapped threadfactory with setDeamon(true), so the 
* threads won't keep the JVM alive when it should otherwise exit. 
*/ 
public class DaemonThreadFactory implements ThreadFactory { 

    private final ThreadFactory factory; 

    /** 
    * Construct a ThreadFactory with setDeamon(true) using 
    * Executors.defaultThreadFactory() 
    */ 
    public DaemonThreadFactory() { 
     this(Executors.defaultThreadFactory()); 
    } 

    /** 
    * Construct a ThreadFactory with setDeamon(true) wrapping the given factory 
    * 
    * @param thread 
    *   factory to wrap 
    */ 
    public DaemonThreadFactory(ThreadFactory factory) { 
     if (factory == null) 
      throw new NullPointerException("factory cannot be null"); 
     this.factory = factory; 
    } 

    public Thread newThread(Runnable r) { 
     final Thread t = factory.newThread(r); 
     t.setDaemon(true); 
     return t; 
    } 
} 

あなたのweb.xmlにコンテキスト・リスナーを追加する必要があります、あなたはまた、あなたが実行したいと思うスレッドの数を指定することができますバックグラウンドジョブ:

<listener> 
    <listener-class>com.example.ExecutorContextListener</listener-class> 
    </listener> 

サーブレットからエグゼキュータにアクセスし、それにジョブを送信:あなたが春を使用している場合

ExecutorService executor = (ExecutorService)getServletContext().getAttribute("MY_EXECUTOR"); 
... 
executor.submit(myJob); 

、このすべては、おそらくsimpler

+0

デーモンではないスレッドがエラーシナリオでtomcatをどのように結びつけますか? –

+0

私はこの道を歩いていましたが、Tomcatがシャットダウンしているときに、確実に正常にExecutorServiceをシャットダウンできないかと心配しています。私は実行中のものを失うことはできません。どうやらServletContextListenerに依存することはできません。 http://stackoverflow.com/questions/1549924/shutdown-hook-for-java-web-applicationおよびhttp://stackoverflow.com/questions/11443133/shutdown-hook-in-tomcat-necessary-not-runningを参照してください。 –

+0

@nosの場合、myJob Runnableは 'while(true){Thread.sleep(1000);}のような実行メソッドを持つ必要があります。 // do something more ..} '.isn't it?] –

関連する問題