Nginx에서 Proxy_send_timeout은 실제로 무엇을 합니까?

Nginx에서 Proxy_send_timeout은 실제로 무엇을 합니까?

Nginx 문서에는 다음과 같이 "백엔드" 서버에 대해 구성할 수 있는 세 가지 다른 시간 제한에 관한 지시문이 있습니다.

proxy_connect_timeout프록시 서버와의 연결 설정에 대한 시간 초과를 정의합니다. 이 시간 초과는 일반적으로 75초를 초과할 수 없다는 점에 유의해야 합니다.

이는 이해하기 쉽습니다. Nginx는 업스트림 "백엔드" 서버에 연결하려고 하며 X 시간 내에 연결할 수 없으면 포기하고 오류를 반환합니다. 서버에 연결할 수 없거나 연결이 너무 많습니다.

proxy_read_timeout프록시 서버에서 응답을 읽는 데 대한 시간 초과를 정의합니다. 시간 초과는 전체 응답 전송에 대한 것이 아니라 두 개의 연속 읽기 작업 사이에만 설정됩니다. 프록시 서버가 이 시간 내에 아무 것도 전송하지 않으면 연결이 닫힙니다.

이는 또한 의미가 있습니다. Nginx는 이미 "백엔드" 서버와 TCP 연결을 설정했으며 이제 실제로 요청을 보내려고 하지만 서버가 처리하는 데 오랜 시간이 걸리고 X보다 많은 시간이 걸리면 닫으십시오. 연결을 해제하고 사용자에게 돌아갑니다.

실제로 Nginx가 연결을 닫는 것에 놀랐습니다. 연결은 유지되지만 사용자에게 오류를 반환할 것이라고 생각했습니다. 시간이 초과될 때마다 "백엔드" TCP 연결을 다시 설정하는 것은 비용이 많이 드는 것 같습니다.

proxy_send_timeout프록시 서버로 요청을 전송하기 위한 시간 초과를 설정합니다. 시간 제한은 전체 요청 전송에 대한 것이 아니라 두 개의 연속 쓰기 작업 사이에만 설정됩니다. 프록시된 서버가 이 시간 내에 아무 것도 수신하지 않으면 연결이 닫힙니다.

이건 잘 이해가 안 가네요. 나에게는 이론이 있지만 누군가가 그것을 확인해 주기를 바랍니다. 이 시간 초과에 대해 제가 생각할 수 있는 유일한 값은 요청 페이로드가 큰 경우입니다(예: JSON을 사용한 대규모 POST 요청 또는 사용자가 저장하려는 문서). 요청을 "백엔드"로 전송하려면 요청을 더 작은 MTU TCP 세그먼트로 나누고 이를 원래 요청의 "청크"로 보내야 합니다. 따라서 기술적으로 모든 청크를 서버에 성공적으로 전송할 때까지 실제로 요청을 보내지 않았습니다. Nginx는 요청의 각 청크 사이의 시간을 측정합니까? 그것이 문서에서 "쓰기"가 의미하는 것입니까? 요청이 실제로 전송되면 Nginx는 proxy_read_timeout?

답변1

TCP/IP는 소위 "스트리밍" 데이터 전송 프로토콜입니다. 이는 TCP/IP 연결을 통해 데이터를 읽는 당사자가 "세그먼트" 또는 패킷의 크기에 대해 반드시 신경 쓸 필요가 없도록 설계되었습니다. 이는 실제로 원격 피어가 보낸 데이터를 얻기 위해 피어가 전통적인 "읽기" 작업을 호출하는 상황으로 해석됩니다(예:readLinux의 경우) 원격 끝이 단일 "쓰기" 작업에 제공한 만큼의 데이터를 한 번에 정확하게 읽을 필요는 없습니다. TCP/IP 프로토콜 구현은 한 번에 "쓰기" 작업으로 전달된 것에서 적절한 크기의 IP 패킷을 변함없이 만들고, 다른 쪽 구현에서는 해당 패킷에서 데이터를 다시 조립합니다. 하지만 그렇지 않을 거야반드시 동일한 데이터 경계를 가진 일부 "읽기" 클라이언트 응용 프로그램에 전달하십시오!

예: A는 모든 외부 시스템 이벤트에 대해 보낼 데이터가 50Kb이므로 동시에 RAM에 모두 담을 수 없으므로 전송 버퍼 크기인 16Kb 단위로 보냅니다. 따라서 먼저 16Kb를 보낸 다음 또 다른 16Kb, 또 다른 16Kb, 마지막으로 2Kb를 보냅니다. TCP/IP 구현은 내부적으로 128Kb 버퍼(예: 커널 버퍼)에 버퍼링된 이러한 50Kb를 보낸 다음 네트워크를 통해서만 보낼 수 있으며 이 역시 자체 조건이 있습니다. 전송 애플리케이션이 인식하지 못하는 방식으로 조각난 이러한 데이터 중 일부는 네트워크 상태로 인해 다른 쪽 끝에 먼저 도착하고 그곳의 TCP/IP 구현에 의해 조립되어 커널 버퍼에 저장됩니다. 다시. 커널은 데이터를 읽으려는 프로세스를 깨워 30Kb를 모두 읽습니다. 수신자는 더 많은 것을 기대하는지, 그리고 얼마나 더 기대할 것인지를 어떻게 이해해야 하는지 결정해야 합니다.체재"메시지"나 데이터는 TCP/IP가 걱정하는 것이 아닙니다.

read이는 예를 들어 Nginx가 Linux 기반 시스템에서 수행할 모든 호출에 대해 클라이언트 요청을 한 번에 얼마나 많이 읽을지 알 수 없음을 의미합니다 .

그러나 문서는 proxy_send_timeout그것이 무엇인지에 대한 약간의 힌트를 제공합니다(강조).

프록시 서버로 요청을 전송하기 위한 시간 초과를 설정합니다. 시간 제한은 전체 요청 전송에 대한 것이 아니라 두 개의 연속 쓰기 작업 사이에만 설정됩니다.프록시된 서버가 이 시간 내에 아무것도 수신하지 못하는 경우, 연결이 닫힙니다.

문제는 Nginx 이후로프록시요청 - 요청이 수행되지 않음을 의미유래하다이를 통해 - "다운스트림" 클라이언트(Nginx에 요청을 보낸 연결의 원격 끝, "프록시" 역할을 하는 Nginx가 이제 업스트림으로 전달할 것으로 예상함)가 요청 데이터를 전송하기 전에 기다립니다. 업스트림 연결을 통해 전달(쓰기)합니다.

내가 이해하는 방식에 따르면 [제한 시간 동안] 다운스트림에서 수신된 것이 없으면 프록시 서버도 아무 것도 수신하지 않고 연결이 닫힙니다.

달리 말하면, 해당 다운스트림이 표시된 시간 내에 아무 것도 보내지 않으면 proxy_send_timeoutNginx는 업스트림과의 연결을 닫습니다.

예를 들어, Nginx에 요청을 보내는 웹 브라우저를 생각해 보세요. 첫 번째 부분은 A 시간에 Nginx에 의해 읽혀집니다. 요청을 일부 업스트림으로 프록시한다고 가정하면 해당 업스트림에 대한 연결을 열고 업스트림 연결 소켓을 통해 브라우저에서 수신한 내용을 전송(쓰기)합니다. 그런 다음 브라우저에서 더 많은 요청 데이터 조각을 읽을 때까지 기다립니다. A 시간에 비해 X 시간 초과 후에 다음 조각이 도착하지 않으면 업스트림에 대한 연결이 닫힙니다.

이것이 반드시 웹 브라우저에 대한 연결을 닫는다는 의미는 아니라는 점에 유의하십시오. 요청에 대해 확실히 일부 HTTP 오류 상태 코드를 반환하지만 웹 브라우저 연결 수명은 다음과 다른 조건 세트에 의해 결정됩니다 proxy_send_timeout. 후자는 업스트림에 대한 Nginx의 연결에만 관련됩니다.

관련 정보