Как предотвратить неисправную трубу 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

Ответ 1

Ваш серверный процесс получил запись SIGPIPE в сокет. Обычно это происходит, когда вы пишете в сокет, полностью закрытый на другой стороне клиента. Это может происходить, когда клиентская программа не дожидается получения всех данных с сервера и просто закрывает сокет (используя функцию close).

В программе на языке C вы обычно пытаетесь установить для игнорирования сигнала SIGPIPE или установки для него обработчика фиктивных сигналов. В этом случае при записи в закрытый сокет будет возвращена простая ошибка. В вашем случае питон, похоже, генерирует исключение, которое может быть обработано как преждевременное отключение клиента.

Ответ 2

Это зависит от того, как вы его протестировали, и, возможно, от различий в реализации стека TCP персонального компьютера и сервера.

Например, если ваш sendall всегда завершается немедленно (или очень быстро) на персональном компьютере, соединение может просто не сломаться во время отправки. Это очень вероятно, если ваш браузер работает на одном компьютере (поскольку нет реальной задержки в сети).


В общем, вам просто нужно обработать случай, когда клиент отключается до того, как вы закончите, обработав исключение.

Помните, что TCP-коммуникации являются асинхронными, но это гораздо более очевидно для физически удаленных подключений, чем для локальных, поэтому такие условия трудно воспроизвести на локальной рабочей станции. В частности, петлевые соединения на одной машине часто почти синхронны.

Ответ 3

Ошибка сломанной трубы обычно возникает, если ваш запрос заблокирован или занимает слишком много времени, а после таймаута на стороне запроса он закроет соединение, а затем, когда сторона-ответчик (сервер) пытается записать в сокет, это будет вызывать неисправную трубку.

Ответ 4

Возможно, это связано с тем, что вы используете два метода для вставки данных в базу данных, и это приводит к замедлению работы сайта.

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