简体   繁体   English

如何防止errno 32 broken pipe?

[英]How to prevent errno 32 broken pipe?

Currently I am using an app built in python. When I run it in personal computer, it works without problems.目前我正在使用 python 内置的应用程序。当我在个人电脑上运行它时,它没有问题。

However, when I move it into a production server.但是,当我将其移至生产服务器时。 It keeps showing me the error attached as below:.它一直向我显示如下附加的错误:。

I've done some research and I got the reason that the end user browser stops the connection while the server is still busy sending data.我做了一些研究,我得到了最终用户浏览器在服务器仍在忙于发送数据时停止连接的原因。

I wonder why did it happen and what is the root cause that prevents it from running properly in production server, while it works on my personal computer.我想知道为什么会发生这种情况,阻止它在生产服务器上正常运行的根本原因是什么,而它在我的个人计算机上运行。 Any advice is appreciated任何建议表示赞赏

    Exception happened during processing of request from ('127.0.0.1', 34226)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 284, in
_handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 641, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 694, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe

Your server process has received a SIGPIPE writing to a socket. 您的服务器进程已收到SIGPIPE写入套接字。 This usually happens when you write to a socket fully closed on the other (client) side. 当您在另一个(客户端)端写入完全关闭的套接字时,通常会发生这种情况。 This might be happening when a client program doesn't wait till all the data from the server is received and simply closes a socket (using close function). 当客户端程序没有等到收到服务器的所有数据并且只是关闭套接字(使用close函数)时,可能会发生这种情况。

In a C program you would normally try setting to ignore SIGPIPE signal or setting a dummy signal handler for it. 在C程序中,您通常会尝试设置忽略SIGPIPE信号或为其设置虚拟信号处理程序。 In this case a simple error will be returned when writing to a closed socket. 在这种情况下,写入已关闭的套接字时将返回一个简单的错误。 In your case a python seems to throw an exception that can be handled as a premature disconnect of the client. 在你的情况下,python似乎抛出一个异常,可以作为客户端的过早断开来处理。

It depends on how you tested it, and possibly on differences in the TCP stack implementation of the personal computer and the server. 这取决于您如何测试它,以及可能取决于个人计算机和服务器的TCP堆栈实现的差异。

For example, if your sendall always completes immediately (or very quickly) on the personal computer, the connection may simply never have broken during sending. 例如,如果您的sendall始终在个人计算机上立即(或非常快速地)完成,则连接在发送期间可能永远不会中断。 This is very likely if your browser is running on the same machine (since there is no real network latency). 如果您的浏览器在同一台计算机上运行(因为没有真正的网络延迟),这很有可能。


In general, you just need to handle the case where a client disconnects before you're finished, by handling the exception. 通常,您只需要通过处理异常来处理客户端在完成之前断开连接的情况。

Remember that TCP communications are asynchronous, but this is much more obvious on physically remote connections than on local ones, so conditions like this can be hard to reproduce on a local workstation. 请记住,TCP通信是异步的,但这在物理远程连接上比在本地远程连接上要明显得多,因此这样的条件很难在本地工作站上重现。 Specifically, loopback connections on a single machine are often almost synchronous. 具体而言,单台机器上的环回连接通常几乎是同步的。

如果您的请求被阻止或需要太长时间通常会发生损坏的管道错误,并且在请求端超时之后,它将关闭连接然后,当响应端(服务器)尝试写入套接字时,它将抛出一个管道坏了。

This might be because you are using two method for inserting data into database and this cause the site to slow down. 这可能是因为您使用两种方法将数据插入数据库,这会导致网站速度变慢。

def add_subscriber(request, email=None):
    if request.method == 'POST':
        email = request.POST['email_field']
        e = Subscriber.objects.create(email=email).save()  <==== 
        return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/')

In above function, the error is where arrow is pointing. 在上面的函数中,错误是箭头指向的位置。 The correct implementation is below: 正确的实现如下:

def add_subscriber(request, email=None):
    if request.method == 'POST':
        email = request.POST['email_field']
        e = Subscriber.objects.create(email=email)
        return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/')

If it's a python a web application or service such as Flask or FastAPI, this error might occur if the production server is configured to timeout a request that takes too long.如果它是 python 和 web 应用程序或服务,例如 Flask 或 FastAPI,如果生产服务器被配置为超时一个花费太长时间的请求,则可能会发生此错误。 There are relevant parameters in Gunicorn and Uvicorn such as GRACEFUL_TIMEOUT and TIMEOUT that need to be configured according to the needs of your application. Gunicorn 和 Uvicorn 中有 GRACEFUL_TIMEOUT 和 TIMEOUT 等相关参数,需要根据你的应用需要进行配置。 You may also want to check your reverse proxy or gateway timeout thresholds.您可能还想检查您的反向代理或网关超时阈值。

Try this code at the top of your program:在您的程序顶部尝试此代码:

from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE,SIG_DFL)

It should fix the issue.它应该解决这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM