HTTP 리버스 프록시가 일반적으로 서버 측이 아닌 프록시 된 연결의 클라이언트 측에서 HTTP Keep-Alive를 활성화합니까?


30

HAProxy는 클라이언트 쪽 (클라이언트 <-> HAProxy)에서 HTTP 연결 유지를 활성화 할 수 있지만 서버 쪽 (HAProxy <-> 서버)에서 비활성화 할 수 있습니다.

일부 고객은 위성을 통해 웹 서비스에 연결하므로 대기 시간은 ~ 600ms이며 keep-alive를 활성화하면 속도가 약간 빨라질 것이라고 생각합니다. 내가 맞아?

이것은 Nginx에서 지원됩니까? 이것은 다른 소프트웨어 및 하드웨어로드 밸런서에서 광범위하게 구현 된 기능입니까? HAProxy 외에 다른 것은 무엇입니까?

답변:


43

편집 : 내 대답은 편집되지 않은 원래 질문에만 적용됩니다.이 질문은로드 밸런서 / 리버스 프록시에서 일반적인지 여부입니다. nginx / product X가이 기능을 지원하는지 잘 모르겠습니다. 리버스 프록시 경험의 99.9 %가 HAproxy를 사용하고 있습니다.

옳은. 서버 쪽이 아닌 클라이언트 쪽의 HTTP 연결 유지.

왜?

몇 가지 세부 정보를 분류하면 이것이 왜 이점인지 신속하게 확인할 수 있습니다. 이 예에서는 www.example.com 페이지를로드한다고 가정하고 해당 페이지에는 3 개의 이미지 img [1-3] .jpg가 포함되어 있습니다.

Keep-Alive없이 페이지를로드하는 브라우저

  1. 클라이언트가 포트 80에서 www.example.com에 대한 TCP 연결을 설정합니다.
  2. 클라이언트는 "/"에 대한 HTTP GET 요청을 수행합니다.
  3. 서버는 URI "/"의 HTML 컨텐츠를 보냅니다 (여기에는 3 개의 이미지를 참조하는 HTML 태그가 포함됨)
  4. 서버가 TCP 연결을 닫습니다
  5. 클라이언트가 포트 80에서 www.example.com에 대한 TCP 연결을 설정합니다.
  6. 클라이언트는 "/img1.jpg"에 대한 HTTP GET 요청을 수행합니다.
  7. 서버가 이미지를 보냅니다
  8. 서버가 TCP 연결을 닫습니다
  9. 클라이언트가 포트 80에서 www.example.com에 대한 TCP 연결을 설정합니다.
  10. 클라이언트는 "/img2.jpg"에 대한 HTTP GET 요청을 수행합니다.
  11. 서버가 이미지를 보냅니다
  12. 서버가 TCP 연결을 닫습니다
  13. 클라이언트가 포트 80에서 www.example.com에 대한 TCP 연결을 설정합니다.
  14. 클라이언트는 "/img3.jpg"에 대한 HTTP GET 요청을 수행합니다.
  15. 서버가 이미지를 보냅니다
  16. 서버가 TCP 연결을 닫습니다

4 개의 별도 TCP 세션이 설정되어 닫혀 있습니다.

Keep-Alive를 사용하여 페이지를로드하는 브라우저

HTTP Keep-Alive를 사용하면 단일 TCP 연결이 여러 HTTP 요청을 차례로 처리 할 수 ​​있습니다.

  1. 클라이언트가 포트 80에서 www.example.com에 대한 TCP 연결을 설정합니다.
  2. 클라이언트는 "/"에 대한 HTTP GET 요청을 수행하고 서버에이를 HTTP Keep-Alive 세션으로 만들도록 요청합니다.
  3. 서버는 URI "/"의 HTML 컨텐츠를 보냅니다 (여기에는 3 개의 이미지를 참조하는 HTML 태그가 포함됨)
  4. 서버 TCP 연결을 닫지 않습니다
  5. "/img1.jpg"에 대한 클라이언트 및 HTTP GET 요청
  6. 서버가 이미지를 보냅니다
  7. "/img2.jpg"에 대한 클라이언트 및 HTTP GET 요청
  8. 서버가 이미지를 보냅니다
  9. "/img3.jpg"에 대한 클라이언트 및 HTTP GET 요청
  10. 서버가 이미지를 보냅니다
  11. HTTP Keep-Alive 시간 초과 기간 내에 더 이상 HTTP 요청이 수신되지 않으면 서버가 TCP 연결을 닫습니다.

Keep-Alive를 사용하면 단 하나의 TCP 연결 만 설정되고 결국 닫힙니다.

Keep-Alive가 더 나은 이유는 무엇입니까?

이에 응답하려면 클라이언트와 서버간에 TCP 연결을 설정하는 데 필요한 사항을 이해해야합니다. 이를 TCP 3 방향 핸드 셰이크라고합니다.

  1. 클라이언트가 SYN (chronise) 패킷을 보냅니다.
  2. 서버는 SYN (chronise) ACK (nowledgement), SYN-ACK를 다시 보냅니다.
  3. 클라이언트는 ACK (nowledgement) 패킷을 보냅니다.
  4. 클라이언트와 서버 모두 TCP 연결이 활성화 된 것으로 간주

네트워크에는 대기 시간이 있으므로 3 방향 핸드 셰이크의 각 단계에는 일정 시간이 걸립니다. 클라이언트와 서버 사이에 30ms가 있다고 가정하면 TCP 연결을 설정하는 데 필요한 IP 패킷의 앞뒤 전송은 TCP 연결을 설정하는 데 3 x 30ms = 90ms가 걸린다는 것을 의미합니다.

그다지 들리지는 않지만 원래 예제에서 4 개의 개별 TCP 연결을 설정해야한다고 생각하면 360ms가됩니다. 클라이언트와 서버 간의 대기 시간이 30ms가 아니라 100ms이면 어떻게됩니까? 그런 다음 4 개의 연결을 설정하는 데 1200ms가 걸립니다.

더 나쁜 것은 일반적인 웹 페이지를로드하기 위해 3 개 이상의 이미지를 요구할 수도 있고 클라이언트가 요청해야하는 CSS, JavaScript, 이미지 또는 기타 파일이 여러 개있을 수도 있습니다. 페이지에 30 개의 다른 파일이로드되고 클라이언트 서버 대기 시간이 100ms 인 경우 TCP 연결을 설정하는 데 얼마나 걸립니까?

  1. 1 개의 TCP 연결을 설정하려면 3 x 대기 시간, 즉 3 x 100ms = 300ms가 걸립니다.
  2. 이 작업은 페이지에 대해 31 번, 페이지에서 참조하는 서로 다른 파일에 대해 30 번씩 수행해야합니다. 31 x 300ms = 9.3 초

30 개의 다른 파일을 참조하는 웹 페이지를로드하기 위해 TCP 연결을 설정하는 데 9.3 초가 걸렸습니다. 그리고 그것은 HTTP 요청을 보내고 응답을받는 데 걸린 시간조차 포함하지 않습니다.

HTTP Keep-Alive를 사용하면 하나의 TCP 연결 만 설정하면 300ms가 걸립니다.

HTTP Keep-Alive가 너무 큰 경우 서버 측에서도 사용하지 않겠습니까?

HAproxy와 같은 HTTP 역방향 프록시는 일반적으로 프록시를 사용하는 백엔드 서버에 매우 가깝게 배포됩니다. 대부분의 경우 리버스 프록시와 백엔드 서버 간의 대기 시간은 1ms 미만이므로 TCP 연결을 설정하는 것이 클라이언트 간의 것보다 훨씬 빠릅니다.

그러나 그 이유는 절반에 불과합니다. HTTP 서버는 각 클라이언트 연결에 대해 특정 양의 메모리를 할당합니다. Keep-Alive를 사용하면 연결이 유지되며, 서버 구성에 따라 Keep-Alive 시간 제한에 도달 할 때까지 서버에서 일정량의 메모리를 사용합니다. .

따라서 HTTP 리버스 프록시의 서버 측에서 Keep-Alive를 사용하는 효과를 고려하면 메모리에 대한 필요성이 증가하고 있지만 프록시와 서버 간의 대기 시간이 너무 짧기 때문에 실제 이점이 없습니다. TCP의 3 방향 핸드 셰이크에 걸리는 시간이 단축되므로 일반적으로이 시나리오에서 프록시와 웹 서버간에 Keep-Alive를 비활성화하는 것이 좋습니다.

면책 조항 : 예,이 설명은 브라우저가 일반적으로 서버에 여러 개의 HTTP 연결을 병렬로 설정한다는 사실을 고려하지 않습니다. 그러나 브라우저가 동일한 호스트에 얼마나 많은 병렬 연결을 할 것인지에 대한 제한이 있으며 일반적으로 계속 유지하기에 충분할 정도로 작습니다.


5
우수한 설명 그램에 대한 명예, 나는 나에게이 질문 누구든지 그렇게 오래 응답을 충분한 시간을 보낸 적이, 내가 확실히 :-) 지금은 매우 명확 응답 역할을이 게시물에 대한 링크를하겠습니다
윌리 Tarreau

2
프록시와 백엔드 간의 연결이 https 인 경우 서버 측에서 keepAlive의 이점이 있습니까?
avmohan

"HTTP 서버는 각 클라이언트 연결에 대해 특정 양의 메모리를 할당합니다."예. 그러나로드 밸런서 당 하나만 연결이 있습니까 (?)? 인터넷에서 클라이언트 당 하나가 아님 (?)
Raedwald

@Raedwald,로드 밸런서가 각 백업 서버에 단일 HTTP 연결을 만드는 것으로 제한되어 있다면 시간이 꽤 나쁠 것입니다. :-)
ThatGraemeGuy

7

Nginx는 양쪽에서 연결 유지를 지원합니다.


프록시와 백엔드 사이에 대기 시간이있는 경우 연결 유지가 백엔드에 유용하다고 말할 수 있습니까? 또한 최적의 연결 유지 연결 수는 무엇입니까?
CMCDragonkai

@CMCDragonkai 백엔드가 전용 서버에있는 경우 네트워크에 따라 연결 대기 시간을 피하는 것이 좋습니다. 황금 평균은 없으며 최적의 숫자는 주로 설정, 환경, 응용 프로그램 및 요청 패턴에 따라 다릅니다.
VBart

이 문제를 해결할 방정식을 찾고 싶습니다!
CMCDragonkai

2
내가 읽은 질문은 nginx가 업스트림에서 keep-alive를 지원하는지 여부가 아니라 nginx가 업스트림에서 keep-alive 비활성화를 지원하는지 여부입니다.
45793
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.