Caching-remote-EJB-3.0-Referenzhandbuch
Ich dachte, wie könnte ich sparen Sie Zeit bei der Suche bis remote-ejb-Referenz durch jndi. Ich hatte eine Anwendung, die benötigt, um arbeiten sehr schnell, es hatte aber auch zu nennen, remote ejb, die bremst.
Also meine Lösung war so etwas wie dieses:
Ich nahm die apache-commons-pool-Bibliothek und verwendet seine StackObjectPool Umsetzung für meine remote-ejb-Referenzen-cache.
private static final ObjectPool pool = new StackObjectPool(new RemoteEjbFactory());
Fabrik sieht man hier:
public static class RemoteEjbFactory extends BasePoolableObjectFactory {
@Override
public Object makeObject() {
try {
return ServiceLocator.lookup(jndi);
} catch (NamingException e) {
throw new ConfigurationException("Could not find remote ejb by given name", e);
}
}
}
Dann nehme ich ein Objekt durch Kreditaufnahme es von pool (wenn kein freies Objekt im Schwimmbad es nutzt die Fabrik zu erstellen):
SomeEjbRemote someEjb = null;
try {
someEjb = (SomeEjbRemoteImpl) pool.borrowObject();
someEjb.invokeRemoteMethod();
} catch (Throwable t) {
if (someEjb != null) {
pool.invalidateObject(someEjb);
}
pool.clear(); //Maybe its not neccessary
someEjb = (SomeEjbRemoteImpl) pool.borrowObject();
someEjb.invokeRemoteMethod(); //this time it should work
}
Und natürlich die Rückgabe ejb zurück zum pool nach erfolgreichem invokacion
finally {
try {
pool.returnObject(someEjb);
} catch (Exception e) {
logger.error("Could not return object to pool.", e);
}
}
So wie ich das verstehe gibt es keine Garantie, dass die remote-Referenz bleiben wird, verbunden, so, wenn wir catch-Ausnahme-Cache remote ejb, wir nur entkräften, dass das Objekt und versuchen Sie es erneut.
Was haltet Ihr von solchen Ansatz? Ist es richtig? Vielleicht sind einige andere Lösungen, Ratschläge?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aus der spec
Zusammenfassung § 4.3.14:
Wenn die Bohne SLSB, jeder Anruf wird serviert von einer EJB in der app. server-pool. Die app. - server synchronisiert, der ruft die EJB-Instanzen, so dass jede EJB-Instanz sind nie gleichzeitig zugegriffen.
Für SFSB, jeder Anruf ist der Versand auf eine konkrete EJB-Instanz, und der app. server nicht synchronisiert den Anruf. Also zwei gleichzeitige Anrufe an das remote-Referenz führen könnte, um einen gleichzeitigen Zugriff auf die EJB-Instanz, die wirft dann ein
javax.ejb.ConcurrentAccessException
. Der Kunde ist verantwortlich für die korrekte Synchronisation der Zugriff auf die remote-Referenz.§ 4.8.5 ist über EJB singleton, wahrscheinlich nicht das, was Sie verwenden.
Ich nehme an, Sie verwenden, SLSB, so dass Sie nicht brauchen, um den pool auf der client-Seite: schauen Sie in den remote-bean einmal, und verwenden Sie die gleiche Referenz von mehreren threads.
Konnten Sie jedoch nicht ein benchmark zu sehen, ob mit mehreren Referenz-verbessert die Leistung, aber der Gewinn -- wenn überhaupt -- ist wohl neglectable vergleichen, um die Kosten für den remote-Aufruf selbst.
Wenn du dann immer noch entscheiden, um mehr als eine remote-Referenz, würde ich vorschlagen, ein anderes design. Basierend auf Ihre Frage ich nehme an, Sie haben ein multi-threaded-app. Sie wahrscheinlich bereits verwenden Sie einen pool für die threads, also ein pool für die Referenz ist vielleicht überflüssig. Wenn jeder thread bekommt eine remote-Referenz, wenn es erstellt wird, und threads zusammengefasst werden, es wird nicht sein, dass viele remote-lookup und das design vereinfacht.
My 2 cents
Bin ich für die Beantwortung JBoss AS, da ich noch wenig Erfahrung mit anderen:s.
Remote-JNDI-Referenzen sind nur (load-balancing) Verbindung-weniger proxies (siehe JBoss clustering-proxy-Architektur). Serialisieren Sie in Ordnung ist, was bedeutet, dass Sie Sie halten können, wie die Mitglieder in anderen EJBs und cache Sie, wie Sie tun (ich weiß nicht, ob Ihr pool serialisiert Objekte, einige caches zu tun).
Hinsichtlich der Ungültigkeitserklärung der Vollmachten:
Die proxies öffnet eine Verbindung nur für die Dauer des Methodenaufrufs, und daher nicht über einen 'connected' Staat per se. Die Stimmrechtsvertreter können darüber hinaus mehrere IP-Adressen und load-balance. In JBoss Liste der Knoten wird dynamisch aktualisiert bei jedem Aufruf der Methode, so dass das Risiko eines Verweises auf eine veraltete gehen zu klein ist. Noch gibt es eine chance, diese zu passieren, wenn alle Knoten nach unten gehen oder der proxy bleibt inaktiv, während alle Knoten-IP-Adressen, die veraltete gehen. Je nach pool-reuse-policy (LRU oder andere?) die Wahrscheinlichkeit, dass der rest der Cache-proxies, sind ungültig, wenn man einmal variieren. Eine faire Politik wird minimieren Sie die Gefahr, dass sehr alte Einträge in den pool, die Sie möchten vermeiden, dass in diesem Szenario.
Mit einer fairen Politik im Ort, die Wahrscheinlichkeit, dass alle veraltete gehen aus dem gleichen Grund steigt, und Ihren 'klaren pool einmal ist stale' Politik Sinn machen würde. Darüber hinaus müssen Sie den Fall von der anderen Knoten nach unten zu berücksichtigen. So wie es jetzt ist, Ihren Algorithmus gehen würde, in eine busy-loop suchen, Verweise, während der andere Knoten ausgefallen ist. Ich würde die Implementierung einer exponential-back-off für die Wiederholungen, oder einfach nur halten es für einen fatalen Fehler machen und die exception eine exception zur Laufzeit, je nachdem, ob Sie Leben können mit der remote-EJB wird nicht mehr für eine Weile oder nicht. Und machen die Ausnahme, die Sie fangen bestimmte (wie RemoteCommunicationFailedException), vermeiden Fang von generischen Ausnahmen oder Fehler, wie Ausnahme -, Fehler-oder Throwable.
Andere Frage, die Sie sich Fragen müssen, ist die Menge der Parallelität, die Sie möchten. Normalerweise proxies sind thread-sicher für SLSBs und einzelnen thread nur für SFSBs. SFSBs selbst sind nicht thread-sicher, und SLSBs serialize access per default. Dies bedeutet, dass, es sei denn, Sie ermöglichen den gleichzeitigen Zugriff auf Ihre EJB-3.1-Bohnen (siehe tss link), müssen Sie eine remote-Referenz auf den thread. Das heißt: Bündelung N SLSB remote-Referenzen geben Sie N threads den gleichzeitigen Zugriff. Wenn Sie ermöglichen den gleichzeitigen Zugriff und schreiben Sie Ihre SLSB als thread-safe bean mit der annotation
@ConcurrencyAttribute(NO_LOCK)
Sie können erhalten unbegrenzten Parallelität mit nur einem proxy, und lassen Sie Ihre gesamte pool. Sie Ihre Wahl.EDIT:
ewernli hatte Recht, der thread-safe-SLSB-proxy erstellt eine neue Instanz auf dem server pro Anruf. Dies ist angegeben in 4.3.14:
Dies bedeutet, dass Sie nicht brauchen, jede pool überhaupt. Nur eine Fernbedienung verwenden, ref.