1

WebLogic でホストされているリモート ステートレス EJB を使用する Spring アプリケーションがあります。

<jee:remote-slsb id="itemService"
    jndi-name="org.example.ItemService"
    business-interface="org.example.ItemService"
    cache-home="false" lookup-home-on-startup="false"
    home-interface="org.example.ItemServiceHome"
    resource-ref="false" refresh-home-on-connect-failure="true">
    <jee:environment>
        java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
        java.naming.provider.url=t3://server1:7101,server2:7101
    </jee:environment>
</jee:remote-slsb>

私のアプリはサーバーからアイテムを取得します:

ItemEntry[] itemEntries = itemService.listAvailableItems(criteria);
for(ItemEntry entry: itemEntries) {
    Item item = itemService.getItemAccessObject(entry.getKey());
    // Do something with item
}

ほとんどの場合、これで問題なく動作します。

ただし、アイテムが非常に新しい (最後の数秒でデータベースに追加された) 場合、アイテムで何かをしようとすると断続的なエラーが発生します。

java.rmi.NoSuchObjectException: CORBA OBJECT_NOT_EXIST 1330446337 No; nested exception is: 
       org.omg.CORBA.OBJECT_NOT_EXIST:   vmcid: OMG  minor code: 1  completed: No

説明したように、新しいオブジェクトの場合、試行の約 50% で失敗が発生するようで、for() ループ内では失敗と成功が混在します。

t3:// アドレスを hostname:port を 1 つだけ含むように変更すると、問題は解決します。

したがって、私の作業理論では、listAvailableItems() 呼び出しはクラスター内の 1 つのサーバーに送信されます。問題のアイテムが到着した場所であり、失敗した getItemAccessObject() 呼び出しは、アイテムがまだ同期している別のサーバーに送信されます。 .

Spring をバイパスして EJB コンテキストを自分で管理すると、問題を再現できません。

質問:

  1. 私の作業理論は現実的ですか?(サーバークラスターは私にとってブラックボックスであることに注意してください)
  2. Spring SimpleRemoteStatelessSessionProxyBean および/または WebLogic クライアントは、クラスターメンバー間で呼び出しをどのように分割しますか?
  3. 一連の呼び出しを同じクラスター メンバーに送信する方法はありますか?
4

1 に答える 1

1

経験的証拠に基づいて、私自身の質問に答えます。

を使用してWeblogicに接続する場合wlclient.jar、コアJavaRTEのIIOP実装を使用します。

を使用してWeblogicに接続する場合wlfullclient.jar、それはWebLogic独自のT3プロトコルを使用します。

IIOP実装は、サーバー間でラウンドロビンを実行します。

T3の実装は、少なくとも可能な限り、単一のサーバーとのセッションを維持しているようです。

于 2012-06-01T13:13:45.067 に答える