0

24 時間年中無休で実行され、新しいモジュールまたは既に読み込まれているモジュールの新しいバージョンを再起動せずに読み込むことができるサービスを作成したいと考えています。

次のような方法でjarファイルからクラスをロードできます。

@FunctionalInterface
public interface IWorker {
    void doStuff();
}
IWorker worker;
try {
    URL[] urls = { new URL("jar:file:" +  "C:\\Users\\...\\out\\artifacts\\workers_jar\\somethingworker.jar"  +"!/") };
    ClassLoader cl = new URLClassLoader(urls);
    Class cls = cl.loadClass("hu.test.worker.SomethingWorker");
    worker = (IWorker) cls.newInstance();
    worker.doStuff();
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

ソフトウェアは、モジュールからロードされたクラスの一部の構成にデータベース テーブルを既に使用しているため、そこに完全なクラス名 (およびおそらく jar へのパス) を格納すると、これを使用できます。私の質問は、これをより良い方法で行うことができますか? これは維持するのがやや難しく、簡単に壊れる可能性があります。また、既にロードされているクラスをロードできるかどうかもわかりません。

4

1 に答える 1

3

壊れる可能性のあるもののいくつかを次に示します。

  1. クラスローダーがアクティブな間、Java は JAR ファイルをロックするため、Windows は JAR ファイルの更新を停止する可能性があります。

  2. メモリリーク。新しいクラス ローダーを作成するたびに、前のクラス ローダーがリークする可能性があります。必要なのは、前のローダーによってロードされた 1 つのクラスの 1 つのインスタンスが引き続き到達可能であることだけであり、ローダーとそれがロードしたすべてのクラスも到達可能になります。

  3. 同じ名前のクラスが 2 つ以上あるため、「奇妙な」動作が発生する可能性があります。ランタイム型システムを根本的に壊すことはありませんが (JVM はそれよりもスマートです)、型キャストなどが予期せず失敗することがわかります。

  4. 再デプロイで問題が発生し、完全な再起動が必要になった場合、「24 / 7」ではなくなります。バグのあるコードを再デプロイし、回復するために完全な再起動が必要な場合も同様です。

  5. 場合によっては、OS、Java のインストール、appserver のインストールなどのアップグレードが必要になることがあります。これには、(少なくとも) サービスの JVM の再起動が必要です。

  6. サーバーにハードウェア障害がある場合、「24 / 7」サービスがダウンします。

(たとえば) フロントに HA プロキシを使用して、サービスの 2 つまたは 3 つのインスタンスを実行することをお勧めします。アップグレードする場合は、1 つのインスタンスを停止し、それをアップグレードしてから、HA プロキシを「反転」して、アップグレードされたインスタンスを「プライマリ」にします。次に、すべてのインスタンスがアップグレードされるまで繰り返します。最後のインスタンスをアップグレードする前に問題が発生した場合は、古いバージョンに戻すオプションがあります。

(クラスター化されたアプリケーション サーバー プラットフォームで Web コンテナーを使用してこれを実装することも、同様に有効な別のアプローチです。)

明らかに、これよりも少し複雑ですが、サービスの複数のインスタンスを実行することは、高可用性を実現する通常の方法です。複数のインスタンスを実行する余裕がない場合、サーバーの再起動を回避するために巧妙なことを行っても、「24 / 7」の要件に完全に対処することにはなりません。

于 2016-03-27T01:02:26.863 に答える