2009-02-03 16 views
10

Tengo un cliente de Python que envía una gran cantidad de datos a través del httlib de la biblioteca estándar. Los usuarios se están quejando de que la aplicación es lenta. Sospecho que esto puede deberse en parte al cliente HTTP que estoy usando.¿Un reemplazo para httplib de python?

¿Pude mejorar el rendimiento reemplazando httplib por otra cosa?

He visto que twisted ofrece un cliente HTTP. Parece ser muy básico en comparación con sus otras ofertas de protocolo.

PyCurl puede ser una alternativa válida, sin embargo, su uso parece ser muy antipático, por otro lado, si su rendimiento es realmente bueno, entonces puedo soportar un poco de código no pitónico.

Por lo tanto, si tiene experiencia en mejores bibliotecas de cliente HTTP de python, cuénteme al respecto. Me gustaría saber qué piensas del rendimiento relativo a httplib y qué piensas de la calidad de la implementación.

ACTUALIZACIÓN 0: Mi uso de httplib es en realidad muy limitado - la sustitución tiene que hacer lo siguiente:

conn = httplib.HTTPConnection(host, port) 
conn.request("POST", url, params, headers) 
compressedstream = StringIO.StringIO(conn.getresponse().read()) 

Eso es todo: No se proxies, redirección o cualquier materia de lujo. Es un HTTP simple. Solo necesito poder hacerlo lo más rápido posible.

ACTUALIZACIÓN 1: Estoy atrapado con Python2.4 y estoy trabajando en Windows 32. Por favor, no me hable sobre mejores formas de usar httplib. Deseo conocer algunas de las alternativas a httplib.

Respuesta

21

A menudo, cuando he tenido problemas de rendimiento con httplib, el problema no ha sido con el httplib en sí, sino con la forma en que lo estoy usando. Éstos son algunos errores comunes:

(1) No realice una nueva conexión TCP para cada solicitud web. Si usted está haciendo un montón de solicitud para el mismo servidor, en lugar de este patrón:

 
    conn = httplib.HTTPConnection("www.somewhere.com") 
    conn.request("GET", '/foo') 
    conn = httplib.HTTPConnection("www.somewhere.com") 
    conn.request("GET", '/bar') 
    conn = httplib.HTTPConnection("www.somewhere.com") 
    conn.request("GET", '/baz') 

debe hacerse lo siguiente:

 
    conn = httplib.HTTPConnection("www.somewhere.com") 
    conn.request("GET", '/foo') 
    conn.request("GET", '/bar') 
    conn.request("GET", '/baz') 

(2) No te serializar sus peticiones. Puedes usar threads o asynccore o lo que quieras, pero si estás realizando múltiples solicitudes desde diferentes servidores, puedes mejorar el rendimiento ejecutándolos en paralelo.

+0

Esa no es una verdadera canalización de HTTP; sigue siendo un HTTP persistente y persistente. Para obtener un verdadero canal de conexión HTTP TRUE, vea este fragmento de código usando Python httplib. [link] (http: // code.activestate.com/recipes/576673-python-http-pipelining/) –

1

Parece que asume que es la biblioteca. Es de código abierto, por lo que valdría la pena verificar el código para ver si lo es.

Mencione que está enviando una gran cantidad de datos a través de HTTP. La ineficiencia puede deberse a la biblioteca, pero HTTP no es el protocolo más eficiente para enviar grandes cantidades de datos. Por otra parte, podría ser el uso simple de la biblioteca (¿está enviando una gran cadena o lista, o está utilizando una secuencia o generadores?).

+0

Sí, pero también estoy probando un montón de otras cosas. Realmente estoy tratando de encontrar los beneficios de otras bibliotecas cliente HTTP. No mantengo el servidor, así que no tengo más remedio que usar HTTP. –

+0

+1 para suposiciones desafiantes. –

+0

Bastante justo. Su pregunta revisada es mucho mejor y lo deja claro :) –

19

Los usuarios se están quejando de que la aplicación es lenta. Sospecho que esto puede deberse en parte al cliente HTTP que estoy usando.

¿Pude mejorar el rendimiento reemplazando httplib por otra cosa?

¿Te sospechoso o que son seguro que esa es httplib? Haga un perfil antes de hacer nada para mejorar el rendimiento de su aplicación.

He encontrado mi propia intuición sobre dónde se gasta el tiempo a menudo es bastante malo (dado que no hay algún kernel de código ejecutado millones de veces). Es realmente decepcionante implementar algo para mejorar el rendimiento, luego levantar la aplicación y ver que no haya ninguna diferencia.

Si no está perfilando, ¡está disparando en la oscuridad!

+0

+1 para recomendar el perfil. –

2

httplib2 es otra opción: http://code.google.com/p/httplib2/

nunca he referenciado o perfilada en comparación con httplib, pero también estaría interesado en cualquier hallazgo allí.


de diciembre actualización 2012: ya no uso httplib2. ahora usando Requests: HTTP For Humans, para cualquier http con Python.

+0

No parece estar en desarrollo muy activo (la última versión, 0.4.0 fue en octubre de 2007), tiene algunos errores graves que es necesario corregir y una versión enrollada = (. – Kurt

+0

Creo que Joe G. todavía está manteniendo pero tiene algunos problemas. –

5

PyCurl es increíble, y un rendimiento extremadamente alto.

0

httplib2 es una muy buena opción. Joe Gregorio ha corregido muchos errores de httplib.

+0

-1 para la respuesta duplicada –

1

Como otros respondieron, httplib2 es una buena alternativa porque maneja los encabezados correctamente y puede almacenar en caché las respuestas, pero dudo que esto ayude en el rendimiento de POST.

Una alternativa que en realidad le podría dar un aumento de rendimiento de la POST, especialmente en Windows, es el new HTTP 1.1 client in Twisted.web

0

Funciona en mi máquina Windows: Con Py 2,3 (sin soporte IPv6) esto es sólo la dirección IPv4 , pero con Py 2.4-2.6 la orden es (en mi host Win XP) primero la dirección IPv6 , luego la dirección IPv4. Como la dirección IPv6 se verifica primero, esto da un tiempo de espera y provoca la llamada slow connect().

Solo he cambiado "localhost" a 127.0.0.1 y comenzó a funcionar 10 veces más rápido (de 1087ms a 87ms). Solución de http://www.velocityreviews.com/forums/t668272-problem-with-slow-httplib-connections-on-windows-and-maybe-otherplatforms.html

+2

¿Por qué normalmente se resuelve en los registros AAAA cuando no se puede enrutar el tráfico IPv6? Eso es solo pedir lentitud en todo tipo de cosas. –