簡體   English   中英

如何防止errno 32 broken pipe?

[英]How to prevent errno 32 broken pipe?

目前我正在使用 python 內置的應用程序。當我在個人電腦上運行它時,它沒有問題。

但是,當我將其移至生產服務器時。 它一直向我顯示如下附加的錯誤:。

我做了一些研究,我得到了最終用戶瀏覽器在服務器仍在忙於發送數據時停止連接的原因。

我想知道為什么會發生這種情況,阻止它在生產服務器上正常運行的根本原因是什么,而它在我的個人計算機上運行。 任何建議表示贊賞

    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

您的服務器進程已收到SIGPIPE寫入套接字。 當您在另一個(客戶端)端寫入完全關閉的套接字時,通常會發生這種情況。 當客戶端程序沒有等到收到服務器的所有數據並且只是關閉套接字(使用close函數)時,可能會發生這種情況。

在C程序中,您通常會嘗試設置忽略SIGPIPE信號或為其設置虛擬信號處理程序。 在這種情況下,寫入已關閉的套接字時將返回一個簡單的錯誤。 在你的情況下,python似乎拋出一個異常,可以作為客戶端的過早斷開來處理。

這取決於您如何測試它,以及可能取決於個人計算機和服務器的TCP堆棧實現的差異。

例如,如果您的sendall始終在個人計算機上立即(或非常快速地)完成,則連接在發送期間可能永遠不會中斷。 如果您的瀏覽器在同一台計算機上運行(因為沒有真正的網絡延遲),這很有可能。


通常,您只需要通過處理異常來處理客戶端在完成之前斷開連接的情況。

請記住,TCP通信是異步的,但這在物理遠程連接上比在本地遠程連接上要明顯得多,因此這樣的條件很難在本地工作站上重現。 具體而言,單台機器上的環回連接通常幾乎是同步的。

如果您的請求被阻止或需要太長時間通常會發生損壞的管道錯誤,並且在請求端超時之后,它將關閉連接然后,當響應端(服務器)嘗試寫入套接字時,它將拋出一個管道壞了。

這可能是因為您使用兩種方法將數據插入數據庫,這會導致網站速度變慢。

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('/')

在上面的函數中,錯誤是箭頭指向的位置。 正確的實現如下:

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('/')

如果它是 python 和 web 應用程序或服務,例如 Flask 或 FastAPI,如果生產服務器被配置為超時一個花費太長時間的請求,則可能會發生此錯誤。 Gunicorn 和 Uvicorn 中有 GRACEFUL_TIMEOUT 和 TIMEOUT 等相關參數,需要根據你的應用需要進行配置。 您可能還想檢查您的反向代理或網關超時閾值。

在您的程序頂部嘗試此代碼:

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

它應該解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM