2009-07-03 11 views
7

Ich frage mich, wie ist der beste Weg, Java-Module zu integrieren, die als separate J (2) EE-Anwendungen entwickelt wurden. Jedes dieser Module bietet Java-Schnittstellen. Die POJO-Entitäten (Hibernate) werden zusammen mit diesen Java-Schnittstellen verwendet, es gibt keine DTO-Objekte. Was wäre der beste Weg, um diese Module zu integrieren, d.h. ein Modul, das die andere Modulschnittstelle aus der Ferne anruft?Welchen Remoting-Ansatz für Java-Anwendungen würden Sie empfehlen?

Ich dachte an: EJB3, Hessian, SOAP, JMS. Es gibt Vor-und Nachteile von jedem der Ansätze.

Leute, was ist deine Meinung oder deine Erfahrungen?

Antwort

8

Nachdem ich mit einigen der Remoting-Technologien experimentiert und festgestellt habe, dass sie universell unfun sind, würde ich jetzt Spring Remoting als eine Abstraktion von der Implementierung verwenden. Es ermöglicht Ihnen, sich auf das Schreiben Ihrer Funktionalität zu konzentrieren und Spring den Remote-Teil mit einigen Config behandeln zu lassen. Sie haben die Wahl zwischen mehreren Implementierungen (RMI, Spring HTTP-Aufrufer, Hessian, Burlap und JMS). Die Abstraktion bedeutet, dass Sie eine Implementierung auswählen und sie einfach austauschen können, wenn sich Ihre Anforderungen ändern. Weitere Informationen finden Sie unter SpringSource docs.

+0

Wir verwenden dies in einem System mit HTTP von Client zu Server (aus Sicherheitsgründen erforderlich) und verwenden sowohl JMS als auch EJB für Service-Anrufe. – Robin

0

Ich würde für SOAP gehen.

JMS wäre effizienter, aber Sie müssten eine Message-Bean für jede Schnittstelle codieren.

SOAP auf der anderen Seite kommt mit vielen nützlichen Toolkits, die Ihre Nachrichtendefinition (WSDL) und alle erforderlichen Handler (Client und Server) generieren, wenn ein EJB gegeben wird.

Mit Soap können Sie (aber müssen Sie nicht) mit Zertifikatsicherheit umgehen und Verbindungen über öffentliche Netzwerke sichern. Da das Standardprotokoll HTTP über Port 80 ist, werden Sie nur minimale Probleme mit Firewalls usw. haben. SOAP ist auch ideal für heterogene Clients (in Ihrem Fall alles, was nicht J2EE ist) mit guter Unterstützung für die meisten gebräuchlichen Sprachen auf den meisten gängigen Plattformen.

+1

JMS ist für asynchrone Kommunikation bestimmt, d.h. Feuer und Vergessen. Wenn Sie also eine Antwort von einem Serviceanruf benötigen, benötigen Sie zwei Nachrichtenkanäle, von denen einer die Nachricht empfängt und der andere die Antwort an den Absender zurücksendet. – pjp

+0

Das Problem, das ich mit SOAP sehe, ist, dass die Verwendung dieser Technik die Definition eines XML-Schemas erfordert, das ich dann verwenden kann, um XML an ein Objekt (JAXB) zu binden. Wie ich in meinem ursprünglichen Beitrag ausgeführt habe, besteht das Ziel darin, DTOs zu eliminieren und, wenn möglich, Modell-Entitäten (Hibernate/JPA) zu verwenden. Das Problem mit DTOs besteht darin, dass die Konvertierungsebene zwischen DTOs und Entitäten erforderlich ist. –

+0

@pjp: Nicht genau. Sie können das Muster mit privaten Warteschlangen (für eine Sitzung) verwenden, um die Antwort zu erhalten. Grundsätzlich erstellt der Client eine temporäre Warteschlange, legt die Eigenschaft ReplyTo für eine Anforderungsnachricht fest und löst die Nachricht in der öffentlichen Anforderungswarteschlange aus. Der Responder empfängt die Anforderungsnachricht, startet die Logik, erstellt eine Antwortnachricht und sendet sie an die temporäre Warteschlange, wie in 'ReplyTo' der Anforderungsnachricht angegeben. –

1

Wenn Sie Netzwerkkommunikation zwischen Java-only-Anwendungen benötigen, ist Java RMI der Weg zu gehen. Es hat die beste Integration, höchste Transparenz und den geringsten Overhead.

Wenn jedoch einige Ihrer Clients nicht Java-basiert sind, sollten Sie wahrscheinlich andere Optionen in Betracht ziehen (Java RMI haben tatsächlich einen IIOP-Dialekt, der jedoch mit CORBA interagieren kann - würde ich nicht empfehlen dies tun, außer es ist für einige Legacy-Code-Integration. Abhängig von Ihren Bedürfnissen sind Webservices wahrscheinlich Ihre Freunde. Wenn Sie mit der Netzwerklast belastet sind, könnten Sie Webservices über Hessian gehen.

+0

+1 RMI ist die einfache und unkomplizierte Lösung :-) – ATorras

1

Sie bedeuten buchstäblich entfernt? Wie in einer anderen Umgebung mit unterschiedlichen Verfügbarkeitsmerkmalen? Mit Netzwerk-Gemeinkosten?

Angenommen, "Ja" wäre mein erster Schritt, einen Service-Ansatz zu nehmen, die Aufruf-Technologie für einen Moment beiseite zu legen. Denken Sie nur über das Design und die Bedeutung Ihrer Dienste nach. Sie wissen, dass sie vergleichsweise teuer zu nennen sind, daher sind kleine beschäftigte Schnittstellen eher eine schlechte Sache. Sie wissen, dass das Dienstsystem zwischen den Aufrufen fehlschlagen kann, sodass Sie statusfreie Dienste bevorzugen. Möglicherweise müssen Sie die Anforderungen nach einem Fehler erneut versuchen, sodass Sie idempotente Service-Designs bevorzugen.

Dann berücksichtigen Sie Verfügbarkeitsbeziehungen. Kann Ihr Client ohne das Remote-System arbeiten? In einigen Fällen können Sie einfach nicht fortschreiten, wenn das Remote-System nicht verfügbar ist (z. B. kann der Mitarbeiter nicht aktiviert werden, wenn Sie nicht zum HR-System gelangen). In anderen Fällen können Sie ein "Feuer-und-Sagen" -Verfahren durchführen "Ich bin später" Philosophie; Warteschlange die Anfragen und verarbeiten Antworten später.

Wo es eine Verfügbarkeitssteigung gibt, scheint es einfach zu sein, eine synchrone Schnittstelle freizugeben. Sie können dies mit SLSB EJBs tun, wenn alles Java EE ist, das funktioniert. Ich neige dazu zu verallgemeinern und erwarte, dass, wenn meine Dienste nützlich sind, auch Nicht-Java-EE-Clients sie wollen. Daher ist SOAP (oder REST) ​​nützlich. Heutzutage ist das Hinzufügen einer Web-Service-Schnittstelle zu Ihrem SLSB ziemlich trivial.

Aber meine Haustier-Theorie ist, dass jedes ausreichend große IT-System benötigt aynch Kommunikation: Sie müssen die Verfügbarkeit Einschränkungen zu entkoppeln.Also würde ich eher nach einer JMS-ähnlichen Beziehung suchen. Eine MDB-Fassade vor Ihren Diensten oder SOAP/JMS ist nicht schwer zu tun. Solch ein Ansatz neigt dazu, die Fehlerfalldesignprobleme hervorzuheben, die wahrscheinlich sowieso lauern würden. JMS neigt dazu, Sie zum Nachdenken zu bringen: "Angenommen, ich bekomme keine Antwort? Angenommen, meine Antwort kommt zu spät?"

3

Der Standardansatz besteht darin, zwischen den verschiedenen Dienstkomponenten einfache RMI zu verwenden. Dies führt jedoch zu Problemen bei der Freigabe Ihrer Java-Schnittstellen und Versionsänderungen an Ihrem Domänenmodell, insbesondere wenn Sie viele Komponenten mit denselben Klassen verwenden.

Führen Sie wirklich jeden Dienst in einer separaten VM aus? Wenn diese EJBs immer miteinander kommunizieren, ist es am besten, sie in dieselbe VM zu stellen und Remote-Prozeduraufrufe zu vermeiden, da diese Dienste ihre LocalInterfaces verwenden können.

Die andere Sache, die Sie beißen kann, ist Hibernate POJOs. Sie können denken, dass dies einfache POJOs sind, aber im Hintergrund Hibernate war damit beschäftigt, dass CGLib versucht, Dinge wie "lazy initialization" zuzulassen. Wenn diese Beans serialisiert und über Remote-Grenzen übertragen werden, kann es passieren, dass eine ungewöhnliche Hibernate-Exception auftritt. Persönlich würde ich lieber einfache DTOs erstellen oder die POJOs als XML ausgeben, um zwischen den Komponenten zu wechseln. Meine Kollegen würden noch einen Schritt weiter gehen und für die Übertragung der Daten aus Performance-Gründen eigene Drahtprotokolle schreiben.

Kürzlich habe ich den MULE ESB verwendet, um verschiedene Servicekomponenten zu integrieren. Es ist ziemlich nett, da Sie eine Mischung aus RMI, Sockets, Webservices usw. haben können, ohne den größten Teil des Kesselblechcodes schreiben zu müssen.

http://www.mulesource.org/display/COMMUNITY/Home

+0

+1 Ich mag den ESB-Ansatz – ATorras

+1

Ich hatte vergessen, wo meine Präferenz für VOs/DTOs herkam - es war fieses Hibernate Lazy-Loading-Problem, wo ihre Sammlung Implementierungen bekommen serialisiert zusammen mit der Hibernate-Sitzung, die im aufrufenden Code effektiv bedeutungslos ist - pass auf das auf. –

+0

Eine schnelle Möglichkeit, die POJOs zu serialisieren, wäre die Verwendung von XStream. Es ist nicht so nützlich wie die Verwendung Ihrer eigenen XSD, aber es ist gut genug, um Daten an von Ihnen kontrollierte Systeme zu senden. http://xstream.codehaus.org/ – pjp

2

Warum würden Sie mit etwas gehen andere als die einfachste Sache, die funktioniert?

In Ihrem Fall klingt das wie EJB3 oder vielleicht JMS, je nachdem, ob die Kommunikation synchron oder asynchron sein soll.

EJB3 ist bei weitem das einfachste auf RMI mit dem Container gebaut, der alle zusätzlichen Funktionen bietet, die Sie benötigen könnten - Sicherheit, Transaktionen, etc. Vermutlich sind Ihre POJOs in einem geteilten Glas und können daher einfach zwischen Ihrem übergeben werden EJBs, obwohl ich dazu tendiere, Wertobjekte selbst zu übergeben. Der andere Vorteil von EJB ist, wenn es richtig gemacht wird, dass es das performanteste ist (das ist nur meine Meinung, übrigens ;-).

JMS ist ein wenig komplizierter, aber nicht viel und ein System, das auf die asynchrone Kommunikation bietet gewisse Feinheiten in Bezug auf die Parallelisierung Aufgaben etc.

Die Performance-Overhead von Web-Services, die unvermeidliche zusätzliche Konfiguration und zusätzliche Punkte des Scheiterns machen sie, IMHO, die Mühe nicht wert, es sei denn, Sie haben eine Anforderung, die ihre Verwendung vorschreibt - ich denke über Interop mit Nicht-Java-Clients oder die Bereitstellung von Daten an externe Parteien hier.

+0

Die Antwort von @pjp erinnert mich daran, warum ich DTOs bevorzuge - für das Lazy Loading funktioniert die Hibernate-Sitzung überall, am auffälligsten in ihren Sammlungsimplementierungen. Wenn diese Objekte serialisiert werden, ist auch die Hibernate-Sitzung, und es ist unwichtig clientseitig, wenn sie aufgerufen wird. Es gibt eine Hibernate.initialize (Object) -Methode, die aufgerufen werden kann, um dies zu umgehen, aber meine Präferenz ist immer noch DTOs –

Verwandte Themen