104, 'Conexión restablecida por pares' error de socket, o que al cerrar un resultado toma en un RST en lugar de Fin?

StackOverflow https://stackoverflow.com/questions/383738

Pregunta

Estamos desarrollando un servicio web Python y un sitio web del cliente en paralelo. Cuando hacemos una petición HTTP desde el cliente al servicio, una llamada plantea sistemáticamente una socket.error en socket.py, en la lectura:

(104, 'Connection reset by peer')

Cuando escucho con Wireshark, los "buenos" y "malos" las respuestas son muy similares:

  • Debido al tamaño de la cabecera 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 cabecera (/ 1.0 200, entonces la cabecera Fecha OK HTTP, etc.). El cliente responde a cada uno con ACK.
  • (Buena petición) el servidor envía un FIN, ACK. El cliente responde con un FIN, ACK. El servidor responde ACK.
  • (solicitud incorrecta) el servidor envía un RST, ACK, el cliente no envía una respuesta de TCP, el socket.error se eleva en el lado del cliente.

Tanto el servicio web y el cliente se están ejecutando en un cuadro de Gentoo Linux x86-64 corriendo glibc-2.6.1. Estamos utilizando Python 2.5.2 dentro de la misma virtual_env.

El cliente es una aplicación de Django 1.0.2 que está llamando httplib2 0.4.0 para hacer peticiones. Estamos firmando peticiones con el algoritmo de OAuth firma, con el token OAuth siempre se establece en una cadena vacía.

El servicio se está ejecutando Werkzeug 0.3.1, que está utilizando wsgiref.simple_server de Python. Corrí a través de la aplicación WSGI wsgiref.validator sin problemas.

Parece que esto debería ser fácil de depurar, pero cuando trazo a través de una buena solicitud en el lado del servicio, que se parece a la solicitud incorrecta, en la función socket._socketobject.close (), convirtiendo los métodos de delegado en maniquí métodos. Cuando el envío o sendto (no recuerdo cuál) método está apagado, la aleta o RST se envía, y el cliente empieza a procesar.

"Conexión reajustada por el par" parece culpar a los servicios, pero no confían en httplib2 tampoco. ¿Puede el cliente será la culpa?

** Además depuración - Parece que el servidor en Linux **

Tengo un MacBook, así que traté de ejecutar el servicio en uno y el sitio web del cliente por el otro. El cliente llama al servidor Linux OS X sin el error (FIN ACK). El cliente OS X llama al servicio de Linux con el insecto (RST ACK, y una (54, 'Conexión restablecida por el interlocutor')). Por lo tanto, parece que es el servicio que se ejecuta en Linux. ¿Es x86_64? Un mal glibc? wsgiref? Todavía estás ...

** prueba adicional - wsgiref ve escamosa **

Hemos ido a la producción con Apache y mod_wsgi, y se repone de conexión han desaparecido. Véase mi respuesta a continuación, pero mi consejo es que ingrese la reiniciación de la conexión y vuelva a intentar. Esto permitirá que su servidor ejecuta OK en el modo de desarrollo, y sólidamente en la producción.

¿Fue útil?

Solución

He tenido este problema. Ver El Python "Conexión cancelada por el usuario" Problema .

Usted tiene (lo más probable) ignorara de pequeños problemas de tiempo basado en el intérprete de Python bloqueo global.

Puede (a veces) corregir esto con una time.sleep(0.01) colocados estratégicamente.

"¿Dónde?" usted pregunta. Ni idea. La idea es proporcionar unos mejores concurrencia de hilos y alrededor de las solicitudes de los clientes. Trate de poner simplemente antes a tomar la pedido, por lo que el GIL se restablece y el intérprete de Python puede despejar cualquier hilo pendientes.

Otros consejos

No utilice wsgiref para la producción. Utilizar Apache y mod_wsgi, o algo más.

Continuamos viendo estos restablece la conexión, a veces con frecuencia, con wsgiref (el backend utilizado 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 al cabo de diez fracasos. httplib2 trata dos veces, pero necesita un poco más. Parece que vienen en racimos, así -. La adición de un segundo sueño 1 podría aclarar el tema

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

Cuando preguntamos a la comunidad dev local para obtener ayuda, alguien confirmó que ven una gran cantidad de restablecimientos de conexión con wsgiref que desaparece en el servidor de producción. Hay un insecto allí, pero va a ser difícil de encontrar.

Me doy cuenta de que está utilizando Python, pero me encontré con este artículo de Java para ser útil.

http: //java.sun. com / JavaSE / 6 / docs / notas técnicas / guías / net / artículos / connection_release.html

Normalmente, se obtendría un RST si lo hace su fin, que no se detiene (es decir, en la que los datos pueden ser desechados por la pila si no se ha enviado y ACK'd) y una aleta normal si se permitir que el cierre a la relajación (es decir, espera el cierre para los datos en tránsito para ser ACK'd).

Tal vez todo lo que necesita hacer es configurar su zócalo para quedarse de manera que se quita la condición de carrera entre un no persistente cierre realizado en el zócalo y los ACK que llegan?

Yo tenía el mismo problema sin embargo con la realización de un proceso de carga de un archivo muy grande utilizando un post-cliente Python peticiones a un nginx + uwsgi backend.

Lo que terminó siendo la causa fue el backend tenía un límite en el tamaño máximo del archivo para cargas inferiores a lo que el cliente estaba tratando de enviar.

El error no apareció en los registros de nuestro uwsgi ya que este límite era en realidad uno impuesto por nginx.

Upping el límite en nginx eliminado el error.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top