RMI vs. SIMON

Status des Themas:
Es sind keine weiteren Antworten möglich.

Diskutiere RMI vs. SIMON im Netzwerkprogrammierung Forum; Hallo zusammen, nachdem es mich schwer angekotzt hat dass RMI Probleme macht wenn man den Client hinter einem Router hat und unbedingt...

  1. tuxedo
    tuxedo Guest
    Hallo zusammen,

    nachdem es mich schwer angekotzt hat dass RMI Probleme macht wenn man den Client hinter einem Router hat und unbedingt Callbacks vom Server aus benutzen will (RMI versucht da immer eine Socketverbindung zurück zum Client aufzubauen...), hab ich mich drangesetzt und eine Alternative gebastelt.
    Ich hab sie mal "SIMON" getauft.

    Simple
    Invocation of
    Methods
    Over
    Network

    Ich hab viel Diskussionen über die Geschwindigkeit von RMI gelesen. RMI wird meist als langsam bezeichnet. Aber je nach Anwendungszweck ist das mehr oder weniger anders zu betrachten.

    Nun, meine erste Alpha von SIMON steht und ich habs mal verglichen mit RMI. Dazu hab ich einen Mini-Test geschrieben.

    Sowohl RMI als auch SIMON haben Serverseitig nur eine einzige Methode:

    Code (Text):

    public byte[] benchmark(byte[] b)
     
    Der Test sieht wie folgt aus:

    Code (Text):

    Erstelle X-Byte großes byte[]
    befülle das byte[] mit Zufallswerten
    Stoppe Zeit (
    für 1000mal:
       rufe die Methode benchmark auf und übergebe das byte[]
    )
     
    Ich habe Tests von 16 Byte Array-Größe bis 65535 Byte gemacht. Client und Server liefen auf der gleichen Maschine. Verbunden wurde über Localhost.

    Testsetup:
    Intel Core2 6420 @ 2,13Ghz
    2GB RAM
    JAVA 6 Update 3
    Tests gestartet aus Eclipse 3.3 heraus

    Das Ergebnis hab ich mal grafisch aufgereitet:
    [​IMG]

    Mein SIMON ist ziemlich Konstant was die Ausführungzeit der Test-Methode angeht.
    RMI variiert da ein wenig und kitzelt stellenweise mehr Speed raus.

    Ein wenig Hintergrundwissen zu SIMON (RMI wird intern auch nicht viel anders funktionieren):

    Der Client holt sich vom Server via serialisierung das Interface des Serverobjets. Damit wird lokal ein Proxy gebastelt. Die Methodenaufrufe des Proxys werden abgefangen und an den Server übermittelt (Name des RemoteObjekts, Name des Remot-Methode (jeweils String), Parametertypen und Argumente (jeweils serialisierte Objekte)). Der Server nimmt die Daten entgegen, führt die besagte Methode mit Argumenten aus und liefert das Ergebnis wieder zurück an den Client (ebenfalls wieder serialisiertes Objekt)). Weitere "interna" wurde übrigens hier diskutiert.

    So, jetzt meine Fragen an euch:

    1) Hattet ihr mit RMI schon mal performanceschwierigkeiten?
    2) Für wie aussagekräftig haltet ihr meine Testergebnisse?
    3) Hat einer nen Plan warum RMI das ganze unterschiedlich schnell ausführt? Die Methodenaufrufe sind immer wieder gleich und die übertragenen Daten sind immer zufällig. Dennoch schwanken die Anzahl der Methodenaufrufe ziemlich stark (von etwa 900 bis über 9000), wohingegen SIMON da immer konstant bei rund 3000 pro Sekunde bleibt.

    Any Ideas?

    - Alex
     
  2. Vielleicht hilft dir diese Seite hier weiter (Klick!)
  3. tuxedo
    tuxedo Guest
    Hmm, kleine negative Ergänzung:

    Über's echte Netzwerk ist SIMON momentan sch**sse langsam. Ein Methodenaufruf dauert rund 300ms ... RMI ist da fast ungebremst schnell.

    Irgendwo _muss_ also noch der Wurm drin sein. *suchengeh*

    Die 3 Fragen interessieren mich jedoch weiterhin.

    - Alex

    [update] Hab den Fehler vorerst mal behoben. Muss die beiden nun mal im lokalen Netzwerk vergleichen ...
     
  4. tuxedo
    tuxedo Guest
    So, neues Messergebnis. RMI ist nur noch einen Funken schneller als SIMON ...

    [​IMG]

    Mein Mini-Test hatte einen Designfehler:

    Die JVM hat scheint mitbekommen dass ich 1000mal immer das gleiche Objekt verschicke ... Nachdem ich jetzt vor jedem Senden das byte[] zufällig neu füllen lasse, liefert SIMON verlässliche Werte. Vorher konnte ich 65kbyte*1000, also rund 65mbyte in unter 2 Sekunden transferieren... Das konnte nicht stimmen.

    Jetzt sieht's besser aus. Für den File-Transfer sind jedoch beide nicht optimal geeignet. Mehr als knapp über 5MByte waren im Test mit 65kbyte/Aufruf nicht drin. Und rund 10Mbyte/s würden sich in dem Netzwerk gut übertragen lassen ...

    Bin dennoch überrascht wie gut die erste Alpha schon funktioniert.

    Meine Frage 3 hat sich mittlerweile erübrigt. Frage 1 und 2 lass ich mal noch offen.

    - Alex
     
  5. Guest
    Guest Guest
    Nur aus Neugier, wie löst du das Callback-Problem ohne eine Verbindung zum Client?
     
  6. HoaX
    HoaX Neues Mitglied
    ich tippe mal entweder mit a) udp hole punching oder b) durch eine verbindung die vom client aus aufbebaut wird
     
  7. tuxedo
    tuxedo Guest
    Naja, ist doch ganz einfach:

    Der Client verbindet sich mit dem Server... Damit haben wir ja EINE Verbindung. Warum RMI diese eine Verbindung nicht nutzt um die Callbacks abzuwickeln ist mir schleierhaft. Meine Implementierung verwendet jedenfalls diese eine Verbindung.

    Auch müssen meine Remote-Objekte nicht von irgendwelchen Klassen erben (z.B. UnicastRemoteObject). Es reicht ein einfaches Interface zu implementieren (welches übrigens keine Methoden mit bringt, dient nur der "erkennung" DASS es ein RemoteObjekt ist).

    Ganz fehlerfrei ist die Sache noch nicht. Will noch "erkunden" wie RMI das macht mit der kurzen Latenzzeit, bzw. ob RMI ebenfalls den Nagle-Algo des TCP-Sockets abschaltet. Desweiteren brauch ich noch ein geschickteres Exception-Handling.

    - Alex
     
  8. tuxedo
    tuxedo Guest
    So, RMI-Sourcecode organisiert und mal reingeschaut...

    In der Tat. Sun schaltet auch den Nagle-Algo ab. Bsp. TCPTransport-Klasse, Sourcecode (JDK5) ab Zeile 572:

    Code (Text):

                // set socket to disable Nagle's algorithm (always send
            // immediately)
            // TBD: should this be left up to socket factory instead?
            try {
            socket.setTcpNoDelay(true);
            } catch (Exception e) {
            // if we fail to set this, ignore and proceed anyway
            }
    Was mich wundert ist, dass Sun den BUfferedInputStream und den BufferedOutputStream verwenden. Da sie beenfalls "flush()" benutzen, wundert's mich warum sie noch Puffern?! Oder hab ich da einen unschlagbaren Vorteil von Buffered*Stream nicht verstanden/gesehen?

    - Alex
     
  9. Hinweis: Du möchtest Java lernen? Vielleicht hilft dir dieses Training hier weiter. Sichere dir hier den Zugriff auf umfangreiches Java-Know How und starte richtig durch!
Die Seite wird geladen...

RMI vs. SIMON - Ähnliche Themen

Simon
Simon im Forum AWT, Swing, JavaFX & SWT
Simon Says für LED Board
Simon Says für LED Board im Forum Java Basics - Anfänger-Themen
Senso bzw SimonSays programmieren
Senso bzw SimonSays programmieren im Forum AWT, Swing, JavaFX & SWT
Master/Detail Block mit SIMON
Master/Detail Block mit SIMON im Forum Plattformprogrammierung
Status des Themas:
Es sind keine weiteren Antworten möglich.
Thema: RMI vs. SIMON