2012-02-25 5 views
3

私はJava EE 6 WebアプリケーションをGlassFish 3.1で実行しています。このアプリケーションは、ローカルSingleton EJB MySingletonの2つのインスタンスを使用します。 MySingletonの各インスタンスは、APIを介して第三者のソフトウェアに接続します。異なる物理サーバー上でEJBを実行しているGlassFish

MySingleton.java

@Singleton 
@LocalBean 
public class MySingleton { 
    @PersistenceContext private EntityManager em;  
    private ThirdPartyAPI thirdPartyAPI; 
    ... 
} 

MySingletonManager.java

@Singleton 
@LocalBean 
public class MySingletonManager { 
    @EJB private MySingleton mySingletonA; 
    @EJB private MySingleton mySingletonB;  ///Aargh! They can't run on the same server!! 
    ... 
} 

ここで制約されている:

  1. サードパーティのソフトウェアプロバイダは、そのソフトウェアは、それぞれを実行することを要求しますイン他の物理サーバー上のThirdPartyAPIの番号
  2. MySingletonは、同じPersistenceContextのクエリとトランザクションに必要なEntityManagerというインジェクションインスタンスを使用します。

制約1を満たすために、私はリモートでシングルトンEJBにアクセスする必要があると思う:私は、アプリケーションサーバに「サーバBにサーバA、mySingletonB上mySingletonAを実行する」のような何かを伝える必要があります。このために、JNDIによってリモートEJBを呼び出す可能性があることがわかります。

制約2を満たすには、GlassSish clusteringを使用する必要があると思います。なぜなら、PersitenceContextをMySingletonの2つのインスタンスにわたって共有する必要があるからです。

残念ながら、私は2つのテクニックを一緒に使用する方法(リモートEJBとクラスタリング)に関する参考資料を見つけることができません。

私は、このシナリオのために推奨されるアーキテクチャについてのヒントや提案、そして最終的に実装ガイドラインを探しています。あなたは、外部EISシステムに接続している場合は、物事の

答えて

2

カップルは...

まず、「正しい」方法は、JCAアダプタを書いて、@Resourceを使用してインスタンスを注入することです。彼らは書くのがかなり簡単ですが、Adam Bienは簡単な例を書いた良い例です。あなたのアプリケーション用のカスタムデータソースを作成するような@Resourceを考えてみてください。一度それをすべて理解すれば、実際にはかなり楽しいです。ソケットや同期を使用するEJBの作成は、JEE6仕様では技術的にサポートされていません。

これを行うと、このアダプタをクラスタの両方のメンバにインストールできます。各クラスタメンバーは、サードパーティ製ソフトウェアの外部インスタンスを指すことができます。いずれかのクラスタメンバーがダウンした場合、すべてがピーチで実行され続けます。

しかし...あなたは本当に物事にシングルトンEJBを持つハードな方法をしたい場合、あなたはおそらく、代わりにこれを行うことができます:

まず、MySingletonManagerを取り除きます。クラスタ化は透過的で、クラスタ化されていることを知らないとは限りません。それはシングルトン状態を持つことができないことを理解することが重要です

@Singleton 
@Remote 
public class MySingleton { 
    @PersistenceContext private EntityManager em;  
    private ThirdPartyAPI thirdPartyAPI; 
    ... 

} 

:第二に、あなたのシングルトンのコードを変更します。ThirdPartyAPIが呼び出し間に状態を保持すると、面白いことが起こります。また、thirdPartyAPIの周りにラウンドロビン接続コードデコレータを配置して、両方のThirdPartyServersに接続する必要があります。最後に、GlassFishクラスタを作成し、クラスタにEJBをデプロイします。

@EJB MySingleton myIns; 

これは、自動的にクラスタ内のどこかにEJBを配置し、そのハンドルを与えます。今、このすべてがうまくいくと仮定し、私は何も見逃しませんでした。デフォルトでは、すべてのEJBへのアクセスがシリアル化されているので、現在は並行性の問題があります。 @ConcurrencyAttribute(NO_LOCK)を追加することもできますが、EntityManagerはスレッドセーフではなく、トランザクションも可能です。

全体として、シングルトンEJBは多くの問題を引き起こします。 JCAアダプタを書く時間を費やす!

+0

ご回答ありがとうございます。トピックの複雑さを考えると、時間が必要です。ところで、「シングルトンは状態を持つことができません」ということについて(最終的にはいくつかの参考文献で)明確にすることができますか? – perissf

+0

Singletons http://java.sun.com/developer/technicalArticles/Programming/singletons/に関するこの興味深い記事が見つかりました。ヒントを教えてください – perissf

+0

クラスタ化されたJ2EE環境のシングルトンは、実際にはクラスタ内のノードごとに1つのSingletonインスタンスを持ちます。さもなければ、単一の失敗点があるでしょう...それゆえ、クラスタ化された環境では、 '本当の'シングルトンではないので、シングルトンに状態を入れる際には、追加の注意が必要です。これを管理する最も簡単な方法は、クラスタ化されたシングルトンに状態を入れないことです。 –

関連する問題