web-dev-qa-db-ja.com

errno 32プロークンパイプを防ぐ方法は?

現在私は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
106
SƲmmēr Aƥ

サーバープロセスはソケットへのSIGPIPEの書き込みを受信しました。これは通常、反対側(クライアント側)で完全に閉じられたソケットに書き込むと発生します。これは、クライアントプログラムがサーバーからのすべてのデータが受信されるまで待機せず、単にソケットを閉じる(close関数を使用)場合に起こります。

Cプログラムでは、通常はSIGPIPEシグナルを無視するように設定するか、それにダミーシグナルハンドラを設定します。この場合、閉じられたソケットへの書き込み時に単純なエラーが返されます。あなたの場合、Pythonはクライアントの早すぎる切断として扱うことができる例外を投げるようです。

75

それはあなたがそれをどのようにテストしたか、そしておそらくパーソナルコンピュータとサーバのTCPスタック実装の違いに依存します。

たとえば、パーソナルコンピュータ上でsendallが常に即座に(または非常に速く)完了する場合、送信中に接続が切断されることは決してありません。お使いのブラウザが同じマシン上で実行されている場合、これは非常に可能性があります(実際のネットワーク待ち時間がないため)。


一般に、終了する前にクライアントが切断した場合は、例外を処理することで対処する必要があります。

TCP通信は非同期であることを忘れないでください。ただし、これはローカルの接続よりも物理的にリモートの接続の方がはるかに明白であるため、このような条件はローカルワークステーションで再現しにくい場合があります。具体的には、単一マシン上のループバック接続はしばしばほぼ同期的です。

8
Useless

パイプが壊れているというエラーは通常、リクエストがブロックされたり時間がかかりすぎたり、リクエスト側のタイムアウト後に接続を閉じてから、応答側(サーバー)がソケットに書き込もうとすると発生します。パイプ破損エラー。

6
Aaren Shar

これは、データベースにデータを挿入するために2つの方法を使用しているために、サイトの速度が低下するためと考えられます。

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