python3 instalar development python sockets wsgi httplib2 werkzeug

instalar - install werkzeug python3



104, error de socket de "Restablecimiento de conexión por pares" o ¿Cuándo el cierre de un socket da como resultado un RST en lugar de FIN? (4)

Estamos desarrollando un servicio web de Python y un sitio web de cliente en paralelo. Cuando hacemos una solicitud HTTP del cliente al servicio, una llamada genera de forma consistente un socket.error en socket.py, en modo de lectura:

(104, ''Connection reset by peer'')

Cuando escucho con wireshark, las respuestas "buenas" y "malas" son muy similares:

  • Debido al tamaño del encabezado de OAuth, la solicitud se divide en dos paquetes. El servicio responde a ambos con ACK
  • El servicio envía la respuesta, un paquete por encabezado (HTTP / 1.0 200 OK, luego el encabezado de fecha, etc.). El cliente responde a cada uno con ACK.
  • (Buena solicitud) el servidor envía un FIN, ACK. El cliente responde con un FIN, ACK. El servidor responde ACK.
  • (Mala solicitud) el servidor envía un RST, ACK, el cliente no envía una respuesta TCP, el socket.error se genera en el lado del cliente.

Tanto el servicio web como el cliente se ejecutan en un cuadro de Gentoo Linux x86-64 ejecutando glibc-2.6.1. Estamos usando Python 2.5.2 dentro del mismo virtual_env.

El cliente es una aplicación Django 1.0.2 que llama a httplib2 0.4.0 para realizar solicitudes. Estamos firmando solicitudes con el algoritmo de firma OAuth, con el token OAuth siempre configurado en una cadena vacía.

El servicio ejecuta Werkzeug 0.3.1, que está utilizando el wsgiref.simple_server de Python. Ejecuté la aplicación WSGI a través de wsgiref.validator sin problemas.

Parece que esto debería ser fácil de depurar, pero cuando rastreamos a través de una buena solicitud en el lado del servicio, se ve como la solicitud incorrecta, en la función socket._socketobject.close (), convirtiendo los métodos delegados en métodos ficticios. Cuando el método send o sendto (no se puede recordar) se apaga, se envía FIN o RST y el cliente comienza a procesar.

El "restablecimiento de conexión por pares" parece culpar al servicio, pero tampoco confío en httplib2. ¿Puede el cliente tener la culpa?

** Mayor depuración: parece servidor en Linux **

Tengo una MacBook, así que traté de ejecutar el servicio en una y el sitio web del cliente en la otra. El cliente Linux llama al servidor OS X sin el error (FIN ACK). El cliente de OS X llama al servicio de Linux con el error (RST ACK, y a (54, ''Restablecimiento de conexión por pares'')). Entonces, parece que es el servicio que se ejecuta en Linux. ¿Es x86_64? Un mal glibc? wsgiref? Sigue buscando...

** Pruebas adicionales: wsgiref parece escamosa **

Hemos ido a producción con Apache y mod_wsgi, y los restablecimientos de conexión se han ido. Vea mi respuesta a continuación, pero mi consejo es que registre el restablecimiento de la conexión y vuelva a intentarlo. Esto permitirá que su servidor funcione correctamente en modo de desarrollo y en producción sólida.


He tenido este problema Ver el problema "Restablecimiento de la conexión por pares" de Python .

Usted (muy probablemente) se ha encontrado con pequeños problemas de sincronización basados ​​en Python Global Interpreter Lock.

Puede (a veces) corregir esto con un time.sleep(0.01) colocado estratégicamente.

"¿Dónde?" usted pregunta. Me gana La idea es proporcionar una mejor concurrencia de subprocesos en y alrededor de las solicitudes de los clientes. Intente ponerlo justo antes de hacer la solicitud para que se restablezca el GIL y el intérprete de Python pueda borrar los hilos pendientes.



No use wsgiref para producción. Usa Apache y mod_wsgi, o algo más.

Continuamos viendo estos reinicios de conexión, a veces con frecuencia, con wsgiref (el servidor de prueba usado por el servidor de prueba werkzeug, y posiblemente otros como el servidor de prueba Django). Nuestra solución fue registrar el error, reintentar la llamada en un bucle y renunciar después de diez fallas. httplib2 intenta dos veces, pero necesitamos algunas más. Parece que también vienen en racimos, agregar 1 segundo de sueño podría solucionar el problema.

Nunca hemos visto una conexión restablecida cuando se ejecuta a través de Apache y mod_wsgi. No sé lo que hacen diferente, (tal vez solo los enmascaran), pero no aparecen.

Cuando le pedimos ayuda a la comunidad de desarrolladores locales, alguien confirmó que ven muchos reinicios de conexión con wsgiref que desaparecen en el servidor de producción. Hay un error allí, pero va a ser difícil encontrarlo.


Normalmente, obtendrías un RST si haces un cierre que no se demora (es decir, en qué datos puede ser descartado por la pila si no se ha enviado y ACK''d) y un FIN normal si permites el cierre demorarse (es decir, la espera cercana para que los datos en tránsito sean ACK''d).

Quizás todo lo que tiene que hacer es configurar su socket para que se prolongue para que elimine la condición de carrera entre un cierre no persistente realizado en el socket y los ACK que llegan.