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 コンテキストを自分で管理すると、問題を再現できません。
質問:
- 私の作業理論は現実的ですか?(サーバークラスターは私にとってブラックボックスであることに注意してください)
- Spring SimpleRemoteStatelessSessionProxyBean および/または WebLogic クライアントは、クラスターメンバー間で呼び出しをどのように分割しますか?
- 一連の呼び出しを同じクラスター メンバーに送信する方法はありますか?