Como evitar errno 32 tubo quebrado?


120

Atualmente, estou usando um aplicativo construído em python. Quando o executo no computador pessoal, ele funciona sem problemas.

No entanto, quando eu o movo para um servidor de produção. Ele continua me mostrando o erro anexado como abaixo:

Eu fiz algumas pesquisas e entendi o motivo pelo qual o navegador do usuário final interrompe a conexão enquanto o servidor ainda está ocupado enviando dados.

Eu me pergunto por que isso aconteceu e qual é a causa raiz que o impede de funcionar corretamente no servidor de produção, enquanto trabalha no meu computador pessoal. Qualquer conselho é apreciado

    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

Será que esta 'resolver' o problema?
Pureferret

Ou conecte-se com o uwsgi, etc.
KyungHoon Kim 4/16

Respostas:


85

O processo do servidor recebeu uma SIGPIPEgravação em um soquete. Isso geralmente acontece quando você escreve em um soquete totalmente fechado do outro lado (cliente). Isso pode estar acontecendo quando um programa cliente não espera até que todos os dados do servidor sejam recebidos e simplesmente fecha um soquete (usando a closefunção).

Em um programa C, você normalmente tentaria configurar para ignorar o SIGPIPEsinal ou configurar um manipulador de sinal fictício para ele. Nesse caso, um erro simples será retornado ao gravar em um soquete fechado. No seu caso, um python parece lançar uma exceção que pode ser tratada como uma desconexão prematura do cliente.


2
Aqui está uma boa resposta sobre o manuseio cliente desconecta: stackoverflow.com/a/180922/276274
Maksim Skurydzin

9

Depende de como você o testou e, possivelmente, de diferenças na implementação da pilha TCP do computador pessoal e do servidor.

Por exemplo, se você sendallsempre termina imediatamente (ou muito rapidamente) no computador pessoal, a conexão pode simplesmente nunca ter sido interrompida durante o envio. Isso é muito provável se o seu navegador estiver executando na mesma máquina (já que não há latência de rede real).


Em geral, você só precisa lidar com o caso em que um cliente se desconecta antes de terminar, manipulando a exceção.

Lembre-se de que as comunicações TCP são assíncronas, mas isso é muito mais óbvio nas conexões fisicamente remotas do que nas locais, portanto, condições como essa podem ser difíceis de reproduzir em uma estação de trabalho local. Especificamente, as conexões de loopback em uma única máquina geralmente são quase síncronas.


Estou testando-o executando "paster serve abc.ini --reload", no entanto, a página da Web nunca foi alcançada. E para a estação de trabalho VMWare, estou usando a opção somente host para conexão de rede. Então, você pode aconselhar alguma maneira de executá-lo corretamente?
SƲmmēr Aƥ

1
Eu acho que é uma pergunta de configuração de rede VMWare separada (receio não saber nada sobre isso). A razão a estação de trabalho eo servidor podem se comportar de maneira diferente está acima, porém, e a solução é apenas para lidar com a exceção comtry ... except
Useless

7

O erro de canal quebrado geralmente ocorre se sua solicitação for bloqueada ou demorar muito e após o tempo limite do lado da solicitação, ele fechará a conexão e, quando o lado da resposta (servidor) tentar gravar no soquete, lançará um erro de tubo quebrado.


3

Isso pode ocorrer porque você está usando dois métodos para inserir dados no banco de dados e isso causa lentidão no site.

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

Na função acima, o erro é onde a seta está apontando. A implementação correta está abaixo:

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('/')
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.