0

ラウンドロビン戦略を使用して、ハードウェアロードバランサーの背後に複数のJBossサーバーが配置されています。すべての(JBoss)クライアントは散発的に接続していましたが、これらは正しく負荷分散されていました。ただし、新しいクライアントは1分間に最大100のクエリを送信しており、これらはすべて同じサーバーに送信されています。

リモートクライアントが初期コンテキストを作成し、ルックアップを実行し、接続の再作成のオーバーヘッドを節約するためにJNDIサーバーへの接続を一定期間(約15秒)維持することが起こっていると思います。これは、2番目とN番目のリクエストが同じサーバーに送信されることを意味します。これを次のコードで証明しました(JBossライブラリを使用するJython)。

def __call__(self):
    p = Properties()
    p[Context.PROVIDER_URL] = "jnp://my.load.balancer:1099"
    p[Context.INITIAL_CONTEXT_FACTORY] = JndiLoginInitialContextFactory.name
    p[Context.SECURITY_PRINCIPAL] = <redacted>
    p[Context.SECURITY_CREDENTIALS] = <redacted>

    ctx = InitialContext(p)
    home = ctx.lookup("ejb/ServerNameService")

    ejbQuery = home.create()


    print "Server name: %s", (ejbQuery.getServerName())

    ctx.close()

これで、同じJVM(複数のスレッド)内で100回呼び出すと、常に同じサーバーになります。新しいJVMでそれを100回呼び出すと、混合が発生します。

クラスタリングテクノロジを使用せずに、JNDIに最初の接続の再ネゴシエーションを強制する方法はありますか?

4

2 に答える 2

4

多分。JNDIは、オブジェクトの一種のキャッシュです。したがって、同じVM内で同じ名前を複数回要求すると、常に同じ結果が得られます。それは正しい振る舞いですが、あなたはそれが好きではありません。

解決策は、インスタンス自体ではなく、JNDIにファクトリを登録することです。このようにして、ファクトリはJNDIから接続を作成するための情報を取得できますが、呼び出されるたびに新しいインスタンスを返します(または内部プールからインスタンスを返します)。

同じアプローチがJDBCでも使用されます。JDBC接続をJNDIキャッシュに追加する代わりに、aDataSourceが追加されます。これはJDBCjava.sql.Connectionインスタンスのファクトリです。

于 2012-05-08T16:34:20.937 に答える
1

ハードウェアロードバランサーが実際に「バランシング」しているものを教えてください。

ハードウェアロードバランサーが独自のJBossリモーティングプロトコルを知っているとは想像できないので、あなたの場合はおそらくJNDIルックアップの負荷分散にすぎません。これは、同じInitialContextから取得したすべてのクライアントスタブが最終的に同じ物理サーバーに移動することを意味します。

ハードウェアロードバランサーが各リクエストをラウンドロビンする必要がある場合、リモート呼び出しは、ロードバランサーでサポートされているプロトコル(HTTPなど)を介して行う必要があります。適切に設定すれば、これはJBossでサポートされるはずです。

もちろん、「実際の」JBossクラスターをセットアップして、JBossコードに負荷分散とフェイルオーバーを処理させることもできますが、JBossクラスタリングコードは非常にバグが多く壊れやすいため、このアプローチでは他の何かを壊してしまう可能性があります。

于 2012-05-08T16:32:21.547 に答える