2010-04-11 9 views
12

Tengo algunos problemas de rendimiento al crear un servidor HTTP Python muy simple. La cuestión clave es que el rendimiento varía según el cliente que utilizo para acceder a él, donde el servidor y todos los clientes se ejecutan en la máquina local. Por ejemplo, una solicitud GET emitida desde una secuencia de comandos de Python (urllib2.urlopen ('http://localhost/') .read()) tarda más de un segundo en completarse, lo que parece lento teniendo en cuenta que el servidor no está cargado. Ejecutar la solicitud GET desde Excel usando MSXML2.ServerXMLHTTP también se siente lento. Sin embargo, al solicitar los datos de Google Chrome o de RCurl, el complemento curl para R, se obtiene una respuesta esencialmente instantánea, que es lo que esperaría.Servidor HTTP Slow Python en el host local

Además de mi confusión es que no tengo ningún problema de rendimiento para ningún cliente cuando estoy en mi computadora en el trabajo (los problemas de rendimiento están en la computadora de mi casa). Ambos sistemas ejecutan Python 2.6, aunque la computadora de trabajo ejecuta Windows XP en lugar de 7.

A continuación se muestra mi ejemplo de servidor muy simple, que simplemente devuelve 'Hola mundo' para cualquier solicitud de obtención.

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 

class MyHandler(BaseHTTPRequestHandler): 
    def do_GET(self): 
     print("Just received a GET request") 
     self.send_response(200) 
     self.send_header("Content-type", "text/html") 
     self.end_headers() 

     self.wfile.write('Hello world') 

     return 

    def log_request(self, code=None, size=None): 
     print('Request') 

    def log_message(self, format, *args): 
     print('Message') 

if __name__ == "__main__": 
    try: 
     server = HTTPServer(('localhost', 80), MyHandler) 
     print('Started http server') 
     server.serve_forever() 
    except KeyboardInterrupt: 
     print('^C received, shutting down server') 
     server.socket.close() 

Tenga en cuenta que en MyHandler sobreescribo las funciones log_request() y log_message(). La razón es que leí que una búsqueda de nombre de dominio totalmente calificado realizada por una de estas funciones podría ser una razón para un servidor lento. Desgraciadamente, configurarlos solo para imprimir un mensaje estático no resolvió mi problema.

Además, observe que he puesto una declaración print() como la primera línea de la rutina do_GET() en MyHandler. La lentitud ocurre antes de que se imprima este mensaje, lo que significa que ninguna de las cosas que vienen después está causando un retraso.

Respuesta

11

Esto no suena como un problema con el código. Una manera ingeniosa de resolución de problemas es un servidor HTTP para conectarse a él al telnet en el puerto 80. A continuación, se puede escribir algo como:

GET /index.html HTTP/1.1 
host: www.blah.com 
<enter> <enter> 

y observar la respuesta del servidor. Vea si obtiene un retraso usando este enfoque.

Es posible que también desee apagar los firewalls para ver si son responsables de la ralentización.

Intente reemplazar 127.0.0.1 para localhost. Si eso resuelve el problema, entonces esa es una pista de que la búsqueda FQDN puede ser la causa posible.

+0

John - Gracias por la sugerencia, con la solicitud vaya a 127.0.0.1 resuelto el problema de la velocidad. Si alguien puede indicarme más información sobre cómo controlar la búsqueda de FQDN, sería útil. – Abiel

+0

Ok ... esto podría significar que urllib2.urlopen() y Excel están haciendo una forma de búsqueda de FQDN en "localhost" que de alguna manera demora para siempre en resolverse. La pregunta es ¿cómo/por qué Chrome y Curl realizan la búsqueda de forma diferente?Podrías probar otras funciones de Python que acceden a http: // (¿llamadas de socket, quizás?) Y ver si esto es algo específico de un intérprete de Python o específico de urllib. Si es un intérprete específico, entonces el sistema operativo/firewall de alguna manera podría tratar procesos como python.exe y Excel de forma diferente a Chrome y curl. – user235859

26

El controlador de la solicitud emite una búsqueda de nombre inverso para mostrar el nombre del cliente en el registro. Mi Windows 7 emite una primera búsqueda de DNS que falla sin demora, seguida por 2 consultas de nombre de NetBIOS sucesivas para el cliente HTTP, y cada uno se ejecuta en un retraso de 2 segundos = 4 segundos de retraso.

Tenga una mirada en http://www.answermysearches.com/xmlrpc-server-slow-in-python-how-to-fix/2140/

Otra solución que funcionó para mí es para anular BaseHTTPRequestHandler.address_string() en mi controlador de solicitudes con una versión que no realiza la búsqueda de nombre

def address_string(self): 
    host, port = self.client_address[:2] 
    #return socket.getfqdn(host) 
    return host 

Philippe

+3

gracias. esto me salvó la vida. –

+1

gracias ... ¡salva mi vida también! – Manish

+1

y el mío! ¡muchas gracias! – buskila

Cuestiones relacionadas