[python] errno 32 깨진 파이프를 방지하는 방법은 무엇입니까?

현재 저는 파이썬으로 빌드 된 앱을 사용하고 있습니다. PC에서 실행하면 문제없이 작동합니다.

그러나 프로덕션 서버로 이동할 때. 다음과 같이 첨부 된 오류가 계속 표시됩니다.

나는 약간의 조사를 해왔고 서버가 여전히 데이터를 보내는 동안 최종 사용자 브라우저가 연결을 중지하는 이유를 얻었습니다.

왜 그런 일이 발생했는지, 그리고 그것이 내 개인용 컴퓨터에서 작동하는 동안 프로덕션 서버에서 제대로 실행되지 못하게하는 근본 원인이 무엇인지 궁금합니다. 조언을 주시면 감사하겠습니다

    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신호 를 무시하도록 설정하거나 이에 대한 더미 신호 처리기를 설정합니다. 이 경우 닫힌 소켓에 쓸 때 간단한 오류가 반환됩니다. 귀하의 경우 파이썬은 클라이언트의 조기 연결 해제로 처리 할 수있는 예외를 throw하는 것 같습니다.


답변

테스트 방법과 개인용 컴퓨터와 서버의 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('/')


답변