xmlrpclib sehr langsam über ethernet

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

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
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Wild geraten: DNS-Lookup-Timeouts?

Stefan
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo Hand!

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

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Au ja, wildes raten, ich tipp mal auf Nagle’s Algorithm. :D
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

@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.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

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
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

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
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten