104,“对等连接重置"套接字错误,或者什么时候关闭套接字会导致RST而不是FIN? [英] 104, 'Connection reset by peer' socket error, or When does closing a socket result in a RST rather than FIN?

查看:262
本文介绍了104,“对等连接重置"套接字错误,或者什么时候关闭套接字会导致RST而不是FIN?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在并行开发Python Web服务和客户端网站.当我们从客户端向服务发出HTTP请求时,一个调用会持续在socket.py中产生一个socket.error,内容为:

We're developing a Python web service and a client web site in parallel. When we make an HTTP request from the client to the service, one call consistently raises a socket.error in socket.py, in read:

(104, 'Connection reset by peer')

当我用Wireshark收听时,好"和坏"的响应看起来非常相似:

When I listen in with wireshark, the "good" and "bad" responses look very similar:

  • 由于OAuth标头的大小,该请求被分为两个数据包.该服务使用ACK响应两者
  • 该服务发送响应,每个报头一个数据包(HTTP/1.0 200 OK,然后是Date报头,等等).客户端使用ACK响应每个请求.
  • (良好请求)服务器发送FIN,ACK.客户端以FIN ACK响应.服务器响应ACK.
  • (错误请求)服务器发送RST,ACK,客户端未发送TCP响应,套接字.客户端出现错误.

Web服务和客户端都在运行glibc-2.6.1的Gentoo Linux x86-64机器上运行.我们在同一个virtual_env中使用Python 2.5.2.

Both the web service and the client are running on a Gentoo Linux x86-64 box running glibc-2.6.1. We're using Python 2.5.2 inside the same virtual_env.

客户端是Django 1.0.2应用,正在调用httplib2 0.4.0发出请求.我们正在使用OAuth签名算法对请求进行签名,并且OAuth令牌始终设置为空字符串.

The client is a Django 1.0.2 app that is calling httplib2 0.4.0 to make requests. We're signing requests with the OAuth signing algorithm, with the OAuth token always set to an empty string.

该服务正在运行使用Python的wsgiref.simple_server的Werkzeug 0.3.1.我通过wsgiref.validator运行了WSGI应用程序,没有任何问题.

The service is running Werkzeug 0.3.1, which is using Python's wsgiref.simple_server. I ran the WSGI app through wsgiref.validator with no issues.

这似乎应该很容易调试,但是当我在服务端跟踪一个好的请求时,看起来就像是一个不好的请求,在socket._socketobject.close()函数中,将委​​托方法变成了伪方法方法.关闭send或sendto(不记得哪个)方法时,将发送FIN或RST,然后客户端开始处理.

It seems like this should be easy to debug, but when I trace through a good request on the service side, it looks just like the bad request, in the socket._socketobject.close() function, turning delegate methods into dummy methods. When the send or sendto (can't remember which) method is switched off, the FIN or RST is sent, and the client starts processing.

对等连接重置"似乎是服务的罪魁祸首,但我也不信任httplib2.客户有错吗?

"Connection reset by peer" seems to place blame on the service, but I don't trust httplib2 either. Can the client be at fault?

**进一步调试-看起来像Linux上的服务器**

** Further debugging - Looks like server on Linux **

我有一台MacBook,所以我尝试在其中一个上运行该服务,并在另一个上运行客户端网站. Linux客户端调用OS X服务器时不会出现错误(FIN ACK). OS X客户端使用错误(RST ACK和一个(54,对等重置连接"))调用Linux服务.因此,它看起来像是在Linux上运行的服务.是x86_64吗?坏glibc? wsgiref?还在寻找...

I have a MacBook, so I tried running the service on one and the client website on the other. The Linux client calls the OS X server without the bug (FIN ACK). The OS X client calls the Linux service with the bug (RST ACK, and a (54, 'Connection reset by peer')). So, it looks like it's the service running on Linux. Is it x86_64? A bad glibc? wsgiref? Still looking...

**进一步测试-wsgiref看起来有些怪异**

** Further testing - wsgiref looks flaky **

我们已经使用Apache和mod_wsgi进行生产,并且连接重置已消失.请参阅下面的答案,但我的建议是记录连接重置并重试.这样一来,您的服务器就可以在开发模式下正常运行,并且可以在生产环境中可靠运行.

We've gone to production with Apache and mod_wsgi, and the connection resets have gone away. See my answer below, but my advice is to log the connection reset and retry. This will let your server run OK in development mode, and solidly in production.

推荐答案

我遇到了这个问题.请参见对等连接重置"问题.

I've had this problem. See The Python "Connection Reset By Peer" Problem.

您(很可能)遇到了基于Python全局解释器锁定的小定时问题.

You have (most likely) run afoul of small timing issues based on the Python Global Interpreter Lock.

您可以(有时)使用策略性放置的time.sleep(0.01)对此进行更正.

You can (sometimes) correct this with a time.sleep(0.01) placed strategically.

在哪里?"你问.甘拜下风.这样做的目的是在客户端请求中及其周围提供更好的线程并发.尝试在发出请求之前 放置它,以便重置GIL,Python解释器可以清除所有挂起的线程.

"Where?" you ask. Beats me. The idea is to provide some better thread concurrency in and around the client requests. Try putting it just before you make the request so that the GIL is reset and the Python interpreter can clear out any pending threads.

这篇关于104,“对等连接重置"套接字错误,或者什么时候关闭套接字会导致RST而不是FIN?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆