(104, 'Connection reset by peer')我使用wireshark监听时,“良好”和“不良”的响应看起来非常相似:
- 由于OAuth头的大小,请求被拆分为两个数据包。服务对两个数据包都做出ACK响应。
- 服务发送响应,每个标头一个数据包(HTTP / 1.0 200 OK,然后是Date头等)。客户端针对每个响应都会回复ACK。
- (良好的请求)服务器发送FIN,ACK。客户端响应FIN,ACK。服务器响应ACK。
- (不良请求)服务器发送RST,ACK,客户端没有发送TCP响应,客户端抛出socket.error错误。
客户端是一个Django 1.0.2应用程序,它使用httplib2 0.4.0进行请求。我们使用OAuth签名算法进行请求签名,其中OAuth令牌始终设置为空字符串。
服务正在运行Werkzeug 0.3.1,该工具使用Python的wsgiref.simple_server。 我使用wsgiref.validator验证了WSGI应用程序,没有发现问题。
看起来这个问题应该很容易调试,但是当我追踪服务端的良好请求时,它看起来与不良请求一样,在socket._socketobject.close()函数中将委托方法转换为虚拟方法。 当send或sendto(记不清了)方法关闭时,发送FIN或RST,并开始处理客户端。
“连接被对等方重置”似乎把责任归咎于服务端,但我也不信任httplib2。 客户端是否有错?
** 进一步调试 - 似乎是运行在Linux上的服务器 **
我有一台 MacBook,所以我尝试在其中一台电脑上运行服务,在另一台电脑上运行客户端网站。Linux 客户端呼叫 OS X 服务器时没有出现错误(FIN ACK)。但是,OS X 客户端呼叫运行在 Linux 上的服务时出现了问题(RST ACK,并且出现了 (54, 'Connection reset by peer') 的错误)。因此,看起来问题出现在运行在 Linux 上的服务上。它是否是 x86_64?是不是有缺陷的 glibc?是 wsgiref 的问题?我们还在继续寻找答案...
** 进一步测试 - wsgiref 看起来不稳定 **
我们已经使用 Apache 和 mod_wsgi 进入生产环境,连接重置的问题已经解决。请参见我的下面的答案,但我的建议是记录连接重置并进行重试。这将使您的服务器在开发模式下正常运行,并在生产环境中牢固可靠。