Как предотвратить поломку трубы errno 32?

121

В настоящее время я использую приложение, построенное на 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
SƲmmēr A
источник
Имеет ли это «решить» проблему?
Pureferret
Или связаться с uwsgi и т. Д.
Кён Хун Ким

Ответы:

85

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

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

Максим Скуридзин
источник
2
Вот хороший ответ относительно обработки отключений клиентов: stackoverflow.com/a/180922/276274
Максим Скуридзин 08
9

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

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


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

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

Бесполезный
источник
Я тестирую его, запустив «paster serve abc.ini --reload», однако веб-страница никогда не была доступна. А для рабочей станции VMWare я использую вариант Host-only для сетевого подключения. Не могли бы вы посоветовать, как его правильно запустить?
SƲmmēr Aƥ
1
Я думаю, что это отдельный вопрос о конфигурации сети VMWare (боюсь, я ничего об этом не знаю). Причина рабочей станции и сервера могут вести себя по- разному выше , хотя, и решение только для обработки исключения сtry ... except
Бесполезные
8

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

Аарен Шар
источник
3

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

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('/')
Калдип К. Риши
источник