2

Spring MVC アプリケーションとして実装されるプラグインを構築しています。このプラグインは、いずれかのサーバーの GUI を介して 3 ~ 6 台の tomcat サーバーにデプロイされます。プラグインの各インスタンスには、サーバー上の情報を収集して中央データベースに保存するための @Scheduled メソッドがあります。

私の問題は、プラグインをアンインストールするための GUI インターフェイスが @Scheduled スレッドの一部を実行したままにすることです。

たとえば、サーバー 1 から 3 がある環境があります。サーバー 1 の GUI を介してプラグインをインストールして有効にします。サーバー 1 から 3 で @Scheduled スレッドを実行するアプリケーションの 3 つのインスタンスが存在します。サーバー 1 でプラグインをアンインストールすると、スレッドはサーバー 1 で確実に強制終了されますが、サーバー 2 または 3 では強制終了されません。

私は以下を実装しましたが、動作は持続します:

@Component
public class ContextClosedListener implements ApplicationListener<ContextClosedEvent> {
    @Autowired 
    ThreadPoolTaskExecutor executor;

    @Autowired 
    ThreadPoolTaskScheduler scheduler;

    public void onApplicationEvent(ContextClosedEvent event) {
        scheduler.shutdown();
        executor.shutdown();
    }  
}

さらに、これを @Scheduled メソッドではなくコンテキスト リスナーとして実装することを考えましたが、メンテナンスと拡張性の理由から Spring に固執したいと思います。

このような環境でスレッドを確実に強制終了するにはどうすればよいですか?

4

1 に答える 1

0

私が持っているいくつかの考え。ThreadPoolTask​​Executor にはメソッド setThreadNamePrefix があり、スレッドのプレフィックスを設定できます。プレフィックスを一意のものに設定し、実行時にそれらのスレッドを見つけて強制終了できます。同じオブジェクトで setThreadGroup メソッドを使用してスレッド グループを設定し、スレッド グループ内のスレッドを停止することもできます。

より適切で安全な解決策は、スケジュールされたジョブにブレークアウト メソッドを作成することです。これは、Thread.stop() を呼び出す古い「頭を撃った」方法ではなく、スレッドを停止するための推奨される方法です。共通のプレフィックスを設定するか、上記のようにスレッド グループを使用することで、これらの Runnables への参照を取得できます。

次の質問は、スレッドを簡単に停止するにはどうすればよいかということです。そのためには、アプリケーションの実装方法によって異なります。私は主に Spring MVC アプリを扱っているので、最初の解決策は、管理タスクを処理するコントローラーを作成することです。これがJBoss、またはJMXを備えた他の大規模なアプリサーバーである場合(TomcatはJMXを提供するように構成できると思いますが、すぐにそのように構成されているとは思いません)、JMX対応のBeanをアプリ サーバー コンソールからスレッドを停止できるようにします。基本的に、スレッドの停止をトリガーする方法を自分自身に与えます。

于 2013-01-23T20:23:41.520 に答える