Harald Kirsch

… ist auch im Web zu Hause.

Methodenaufrufe über Netz (RPC, RMI)

Remote Procedure Call, Remote Method Invocation oder wie auch immer man es nennt, manchmal ist es hilfreich, wenn man die Verarbeitung seiner Daten auf mehrere Rechner verteilen kann.

Zunächst hatte ich mir Storm angeschaut. Das ist ein komplettes Framework für verteiltes Rechnen. Ich habe mich ernsthaft bemüht es zu verwenden, habe es dann aber aufgeben: Zum einen entspricht es in meiner Anwendung den Kanonen für die Spatzenjagt, zum anderen verlangt es einen Zoo obskurer Klassenbibliotheken und zum dritten kollidierten auch noch einige Versionen der weniger obskuren mit den Versionen die ich benötigte.

Bei Hadoop befürchtete ich Ähnliches, benötige aber insbesondere kein map-reduce, also habe ich es erst garnicht angeschaut.

Meine Anforderungen sind recht einfach:

  • Java
  • Aufruf einer Methode in einem Server auf einem anderen Rechner.
  • Einfach

Schließlich habe ich mir folgende Kandidaten etwas genauer angeschaut:

Lauffähigen Code habe ich bisher mit RMI und Hessian geschrieben und war positiv überrascht, dass das im Prinzip einfach ist, dennoch haben beide Technologien in meinen Augen ihre Macken. Ich versuche mal einen Überblick zu schaffen.

RMI Hessian Google PB Thrift
IDL Compiler
oder Reflection
reflection reflection Compiler Compiler
Server im JDK Servlet Container eingebaut
diverse
Programmiersprachen
ja ja ja

Für mich habe ich folgende Schlüsse aus gezogen:

  • Bei Apache Thrift und bei Google Protocol Buffers muss ich die Schnittstelle aus einer Interfacebeschreibung compilieren.
  • Bei den Google PB muss man offenbar seinen Server selber schreiben, da es sich "lediglich" um ein Serialisierungsprotokoll handelt.
  • Für Hessian braucht man immer einen Servletcontainer wie zum Beispiel Tomcat oder Jetty. Je nach Anwendung kann das ganz schön lästig sein.
  • RMI funktioniert wirklich nur für Java. Außerdem arbeitet es immer mit mindestens zwei TCP-Ports: der erste wird für eine Registry verwendet, die dann jedem Serviceobjekt wieder einen eigenen Port zuweist. Durch eine Firewall kann das schwierig werden. Dazu kommt, dass RMI davon abhängt, seinen eigenen Rechnernamen korrekt zu kennen. Es nutzt nichts wenn der Client den Zielserver ansteuern kann. Der Zielserver muss auch noch den Namen kennen, unter dem der Client ihn sieht, da dieser Name dann dem Client als Ziel für das eigentliche Serviceobjekt mitgeteilt wird.

Da ich nur eine Lösung für Java suche, würde mir im Grunde RMI völlig ausreichen. Aber das Theater mit dieser Registry müsste man noch irgendwie loswerden. Einfach IP-Adresse und Port des Zielrechners angeben und los, das wäre mir am liebsten: keine Registry, kein Serveletcontainer und vor allem kein IDL Compiler. Aber das scheint es derzeit nicht zu geben.

Schließlich ist es Hessian geworden. Wenn der Tomcat einmal konfiguriert ist, geht das problemlos. Messungen eines Kollegen zeigen, dass bei den großen Datenblöcken, die wir übertragen, der HTTP-Wasserkopf nicht ins Gewicht fällt.

My recent experiment is an HTML app showing Open Street Map maps. It is particularly targeted on mobile devices with Javascript support for geolocation.

Here is the map.