Seite 1 von 1

xmlrpclib sehr langsam über ethernet

Verfasst: Dienstag 13. Januar 2009, 00:27
von Hand
Hallo leute,

ich habe die xml-rpc Kommunikation aus dem Beispiel mit Python 2.6
nachgebaut und die Clientanfrage in eine while Loop gesteckt (Geschwindigkeitstest):

Server:

Code: Alles auswählen

import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer

def is_even(n):
    return n%2 == 0

server = SimpleXMLRPCServer(("", 8000))
print "Listening on port 8000..."
server.register_function(is_even, "is_even")
server.serve_forever()
Client:

Code: Alles auswählen

import xmlrpclib

proxy = xmlrpclib.ServerProxy("http://ip:8000/")
while 1:
    print "3 is even: %s" % str(proxy.is_even(3))
    print "100 is even: %s" % str(proxy.is_even(100))
Wenn Server und Client auf Localhost laufen geht alles super schnell,
die Seiten in der Konsole scrollen nur so durch.

Wenn ich jetzt aber Server und Client auf 2 verschiedenen Rechnern,
die über einen Switch miteinander verbunden sind laufen lasse,
wir die Sache sehr langsam und er schafft max 3-5 Request pro Sekunde.

Woran könnte das liegen?

Andreas

Verfasst: Dienstag 13. Januar 2009, 11:40
von sma
Wild geraten: DNS-Lookup-Timeouts?

Stefan

Verfasst: Dienstag 13. Januar 2009, 11:56
von gerold
Hallo Hand!

Vielleicht hilft dir dieser Thread http://www.python-forum.de/topic-11029.html weiter.

mfg
Gerold
:-)

Verfasst: Dienstag 13. Januar 2009, 22:03
von Hand
Hat leider nichts gebracht, habe mit dem Server local und remote experimentiert.

Server:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Einfacher XMLRPC-Server
"""

from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
from random import randint

class SimpleXMLRPCRequestHandler_(SimpleXMLRPCRequestHandler):
    def address_string(self):
        # Disable reverse name lookups
        return self.client_address[:2][0]

class XmlrpcHandler:
    def get_random_int(self, from_int, to_int):
        return randint(from_int, to_int)

server = SimpleXMLRPCServer(("", 50505), SimpleXMLRPCRequestHandler_)
server.register_instance(XmlrpcHandler())
print "Der XMLRPC-Server horcht auf Port 50505."
print "Er kann mit STRG+C oder STRG+PAUSE beendet werden."
server.serve_forever()
Client:

Code: Alles auswählen


import xmlrpclib
import time
import threading

active = True
def shutdown():
    global active
    active = False

s = xmlrpclib.ServerProxy('http://192.168.0.117:50505')
#s = xmlrpclib.ServerProxy('http://localhost:50505')

i = 0

t1 = threading.Timer(5.0, shutdown)
t1.start()
time.clock()
while active:
    i +=1
    s.get_random_int(2,3)  # Returns 2**3 = 8
print
print int(1/(time.clock()/i))
Ergebnis:
Lokal 156 Requests / s
Remote 4 Requests / s

Meine Idee währe jetzt aus einer c++ XMLRPC Lib ein
Python-Modul zu kompilieren.

Verfasst: Dienstag 13. Januar 2009, 23:40
von Leonidas
Es gibt ja C/C++ Module die XML-RPC Libs wrappen, aber so ein unterschied zwischen Lokal und Remote wird eher nicht daran liegen, dass das Modul in Python geschrieben ist, denn das ist ja sowohl Lokal als auch Remote der Fall.

Verfasst: Mittwoch 14. Januar 2009, 09:25
von veers
Au ja, wildes raten, ich tipp mal auf Nagle’s Algorithm. :D

Verfasst: Donnerstag 15. Januar 2009, 19:56
von Hand
@veers
Was meinst du damit?

Bin jetzt der Meinung das xml-rpc in Python schlecht implementiert ist,
mit einem C-Modul läufts 1000x schneller.

Ein Wechsel der Python-Versionen hat auch nichts bewirkt.

Da das Python xml-rpc lokal schnell läuft denke ich es ist ein Bug
in der Socket-Ansteuerung, seit 2004 wurde an dem Modul nichts mehr geändert.

Alternativen wie JSON-RPC oder ICE sind wahrscheinlich besser für schnelle
Kommunikation geeignet da sie binär implementiert sind bzw. keinen so großen Overhead besitzen.

Verfasst: Freitag 16. Januar 2009, 10:15
von veers
Hand hat geschrieben:@veers
Was meinst du damit?
http://www.google.ch/search?q=naggles+algorithm
Erstes Ergebnis:
http://en.wikipedia.org/wiki/Nagle%27s_algorithm

- Jonas

Verfasst: Dienstag 24. März 2009, 23:11
von Hand
So ich bin jetzt weiter.

Python xmlrpclib schliesst die Verbindung nach dem Request wieder

Nach dem ich eine com xmlrpc Lib in Python eingebunden habe gehts schneller:

from comtypes.client import CreateObject
xmlrpcserver = CreateObject("comxmlrpc.rpcClient")

xmlrpcserver.uri = "http://localhost:8000/"
p = ["Hello"]
print xmlrpcserver.execute("Test",p)


xmlrpclib: 391ms per Request
comxmlrpc: 95ms per Request

Verfasst: Mittwoch 25. März 2009, 15:33
von gerold
Hallo Hand!

Hat das irgendeinen Sinn, was du da testest? Warum schickst du sehr viele Requests hintereinander an den Server? Wenn du mehr Daten zurück bekommen willst, dann erstelle eine Funktion, welche dir die Daten in einem Rutsch zurück liefert.

Wenn du trotzdem schnell hintereinander ein paar Funktionen ausführen möchtest, dann kannst du ``xmlrpclib.MultiCall`` dafür verwenden. Damit werden mehrere Anfragen in einem Rutsch zum Server gesendet und in einem Rutsch beantwortet. Du kannst dann durch das Ergebnis iterieren. --> Beispiel: siehe main-Funktion des xmlrpclib-Moduls.

Das Netz ist, wie bei Datenbankanwendungen, der Flaschenhals der Anwendung. Deshalb vermeidet man tunlichst, viele kleine Anfragen hintereinander zu senden. Man versucht, über das Netz so wenig wie möglich Daten zu übertragen (man filtert bereits auf dem Server). Wenn du statt einem einfachen Protokoll (XMLRPC) eine Möglichkeit brauchst, schnell und oft viele Daten zu übertragen, dann ist XMLRPC **nichts** für dich.

mfg
Gerold
:-)