[HTTP 완벽 가이드] 04 커넥션 관리_멍청한 프락시? 내가 더 멍청한디...

Chaejung·2022년 8월 19일
1
post-thumbnail

HTTP 완벽 가이드

지난 HTTP URL, 메시지에 이어서 이번에는 커넥션이다.
언제 한 번 HTTP, HTTPS 차이를 찾다가 TCP/IP를 본 적이 있는데,
사실 무슨 말인지 도통 이해가 되지 않았다.
또한 백엔드 면접 질문으로도 종종 나온다는 TCP/IP...
대충 넘어갈 순 없지.
비록 프론트엔드 공부 중이지만 최선을 다해 공부했다.

중요하다고 생각한 점

TCP 커넥션

일단 (TCP/IP) 커넥션이 맺어지면 클라이언트와 서버 컴퓨터 간에 주고받는 메시지들은 손실 혹은 손상되거나 순서가 바뀌지 않고 안전하게 전달된다.(메시지가 충돌하거나 유실되지 않더라도, 컴퓨터나 네트워크가 고장 나면 클라이언트와 서버 간의 통신에 심각한 문제가 생길 수 있다. (85쪽)

TCP 커넥션은 네 가지 값으로 식별한다.
<발신지 IP 주소, 발신지 포트, 수신지 IP 주소, 수신지 포트> (89쪽)

TCP API는, 기본적인 네트워크 프로토콜의 핸드셰이킹, 그리고 TCP 데이터 스트림과 IP 패킷 간의 분할 및 재조립에 대한 모든 세부사항을 외부로부터 숨긴다. (90쪽)

내가 이해한 TCP 커넥션은 클라이언트와 서버 사이에 일종의 파이프를 구축하는 것.
그리고 그 파이프는 아무도 방해할 수 없는 queue의 형태여서
요청 응답 메시지들이 신뢰성 있게 전달되는 것이다.

확인응답 지연

확인응답이 같은 방향으로 가는 데이터 패킷에 편승되는 경우를 늘리기 위해서, 많은 TCP 스택은 '확인응답 지연' 알고리즘을 구현한다. 확인응답 지연은 송출할 확인응답을 특정 시간 동안(보통 0.1~0.2초) 버퍼에 저장해 두고, 확인응답을 편승시키기 위한 송출 데이터 패킷을 찾는다. 만약 일정 시간 안에 송출 데이터 패킷을 찾지 못하면 확인응답은 별도 패킷을 만들어 전송된다.

운영체제에 따라 다르지만, 지연의 원인이 되는 확인응답 지연 관련 기능을 수정하거나 비활성화할 수 있다.(95쪽)

TCP 느린 시작(slow start)

TCP 커넥션은 시간이 지나면서 자체적으로 '튜닝'되어서, 처음에는 커넥션의 최대 속도를 제한하고 데이터가 성공적으로 전송됨에 따라서 속도 제한을 높여나간다. 이렇게 조율하는 것을 TCP 느린 시작이라고 부르며, 이는 인터넷의 급작스러운 부하와 혼잡을 방지하는 데 쓰인다. (95쪽)

'튜닝'된 커넥션은 더 빠르기 때문에, HTTP에는 이미 존재하는 커넥션을 재사용하는 기능이 있다. (96쪽)

지속 커넥션

따라서 HTTP/1.1(HTTP/1.0의 개선 버전)을 지원하는 기기는 처리가 완료된 후에도 TCP 커넥션을 유지하여 앞으로 있을 HTTP 요청에 재사용할 수 있다. 처리가 완료된 후에도 계속 연결된 상태로 있는 TCP 커넥션을 지속 커넥션이라고 부른다. (104쪽)

병렬 커넥션의 단점

  • 각 트랜잭션마다 새로운 커넥션을 맺고 끊기 때문에 시간과 대역폭이 소요된다.
  • 각각의 새로운 커넥션은 TCP 느린 시작 때문에 성능이 떨어진다.
  • 실제로 연결할 수 있는 병렬 커넥션의 수에는 제한이 있다. (104쪽)

멍청한 프락시의 문제

특히 문제는 프락시에서 시작되는데, 프락시는 Connection 헤더를 이해하지 못해서 해당 헤더들을 삭제하지 않고 요청 그대로를 다음 프락시에 전달한다. 오래되고 단순한 수많은 프락시들이 Connection 헤더에 대한 처리 없이 요청을 그대로 전달한다. (108쪽)
(중략)
프락시는 같은 커넥션상에서 다른 요청이 오는 경우는 예상하지 못하기 때문에, 그 요청은 프락시로부터 무시되고 브라우저는 아무런 응답 없이 로드 중이라는 표시만 나온다. (110쪽)

파이프라인 커넥션 제약 사항

HTTP 클라이언트는 POST 요청같이 반복해서 보낼 경우 문제가 생기는 요청은 파이프라인을 통해 보내면 안 된다. 에러가 발생하면 파이프라인을 통한 요청 중에 어떤 것들이 서버에서 처리되었는지 클라이언트가 알 방법이 없다. POST와 같은 비멱등(nonidempotent) 요청을 재차 보내면 문제가 생길 수 있기 때문에, 문제가 있는 상황에서 그런 위험한 메서드로 요청을 보내서는 안 된다. (114쪽)
(중략)
비멱등인 메서드나 순서에 대해 에시전트가 요청을 다시 보낼 수 있도록 기능을 제공한다 하더라도, 자동으로 재시도하면 안 된다. 예를 들어 대부분 브라우저는 캐시된 POST 요청 페이지를 다시 로드하려고 할 때, 요청을 다시 보내기를 원하는지 묻는 대화상자를 보여준다.

멱등과 비멱등! 이전 백엔드 기술면접 특강 때 처음 만났던 개념인데, 수학 용어라서 굳이 알아야 하나 싶었지만 다시금 만나게 되어서 반갑고 중요성을 깨닫게 되었다.
예를 들어 작성, 신청 및 결제(POST요청 기반)창에서 새로고침이나 뒤로 가기를 누를 경우 종종 나타나는 화면이 이 비멱등 요청에 대한 처리를 확실히 하기 위해서 필요한 작업이지 않을까.

의문이 든 점

확인 응답 지연/네이글 알고리즘

읽다보니 이 둘의 차이가 잘 파악이 되지 않아,
표로 정리해보았다.
차이의 핵심은 둘 다 성능 저하의 원인이지만,
전자는 확인응답에 대한 지연, 후자는 데이터 전송에 대한 지연

구분확인 응답 지연네이글 알고리즘
지연 발생 원인요청과 응답 두 가지 형식으로만 이루어지는 HTTP 동작 방식은 확인 응답이 송출 데이터 패킷에 편승할 기회를 감소TCP가 작은 크기의 데이터를 포함한 많은 수의 패킷을 전송하면 네트워크 성능이 크게 떨어지기 때문
목적확인응답이 같은 방향으로 가는 데이터 패킷에 편승(piggyback)되는 경우를 늘리기 위해
인터넷의 혼잡을 제어하기 위해
네트워크 효율을 높이기 위해
데이터를 한데 모아 한 번에 전송하기 위해
방식송출할 확인응답을 특정 시간 동안(보통 0.1~0.2초) 버퍼에 저장
-> 확인응답을 편승시키기 위한 송출 데이터 패킷 탐색
-> 만약 일정 시간 안에 송출 데이터 패킷을 찾지 못하면 확인응답은 별도 패킷을 만들어 전송
패킷을 전송하기 전에 많은 양의 TCP 데이터를 한 개의 덩어리로 병합
세그먼트가 최대 크기가 되지 않으면 전송을 하지 않는다.
-> 다른 모든 패킷이 확인응답을 받았을 경우에는 최대 크기보다 작은 패킷의 전송을 허락
-> 다른 패킷들이 아직 전송 중이면 데이터는 버퍼에 저장
-> 전송 후 확인응답을 기다리던 패킷이 확인응답을 받았거나 전송하기 충분할 만큼의 패킷이 쌓였을 때 버퍼에 저장되어 있던 데이터 전송
차이점확인응답을 100~200ms 지연시킴확인응답이 도착할 때까지 데이터 전송을 멈추고 있음
해결 방법운영체제에 따라 다르지만, 관련 기능을 수정하거나 비활성화 가능HTTP 스택에 TCP_NODELAY 파라미터 값을 설정하여 네이글 알고리즘을 비활성화
(이 설정 시 작은 크기의 패킷이 너무 많이 생기지 않도록 큰 크기의 데이터 덩어리를 만들어야 함)

대역폭

단일 커넥션의 대역폭 제한과 커넥션이 동작하지 않고 있는 시간을 활용하면, 객체가 여러 개 있는 웹페이지를 더 빠르게 내려받을 수 있을 것이다. (102쪽)

문제

  1. TCP 관련 지연을 해결 할 수 있는 방법에 대한 설명입니다. 빈칸을 채우세요.

운영체제에 따라 다르지만, 확인응답이 같은 방향으로 가는 ((1)                          )되는 경우를 늘리기 위해 구현된 확인응답 지연 관련 기능을 수정하거나 비활성한다. (95쪽)
CP 커넥션은 시간이 지나면서 자체적으로 '튜닝'되어서, 처음에는 커넥션의 최대 속도를 제한하고 데이터가 성공적으로 전송됨에 따라서 속도 제한을 높여나간다. 이렇게 조율하는 것을 ((2)                              )이라고 부르며, 이는 인터넷의 급작스러운 부하와 혼잡을 방지하는 데 쓰인다. (95쪽)
네이글 알고리즘은 세그먼트가 최대 크기(패킷의 최대 크기는 LAN상에서 1,500 바이트 정도, 인터넷상에서는 수백 바이트 정도다)가 되지 않으면 전송을 하지 않는다. 다만 ((3)                                            )에는 최대 크기보다 작은 패킷의 전송을 허락한다. (96쪽)
HTTP 어플리케이션은 성능 향상을 위해서 HTTP 스택에 ((4)                        )을 설정하여 네이글 알고리즘을 비활성화하기도 한다. 이 설정을 했다면, 작은 크기의 패킷이 너무 많이 생기지 않도록 큰 크기의 데이터 덩어리를 만들어야 한다.

  1. 지속 커넥션과 병렬 커넥션에 대한 설명으로 옳은 것은?

(1) 현재 최신 브라우저들은 최대 4개의 병렬 커넥션을 지원한다.
(2) 병렬 커넥션 사이에는 소프트웨어와 관련된 지연이 발생하지 않는다.
(3) 지속 커넥션 요청 헤더에 Connection: Keep-Alive이 있다면 커넥션이 유지되는 것이 보장된다.
(4) 지속 커넥션이 끊어지기 전에 엔터티 본문의 길이를 알 수 있어야 커넥션을 유지할 수 있다.
(5) 프락시에서 Connection 헤더가 문제가 되는 이유는 프락시가 Connection 헤더를 임의로 변환하여 요청을 잘못 보내기 때문이다.


<답>


  1. (1) 데이터 패킷에 편승
    (2) TCP 느린 시작
    (3) 다른 모든 패킷이 확인응답을 받았을 경우
    (4) TCP_NODELAY 파라미터 값
  2. (4)
    (1) 현재 최신 브라우저들은 대부분 6-8개의 병령 커넥션을 지원한다. (103쪽)
    (2) 각각의 새로운 커넥션은 TCP 느린 시작 때문에 성능이 떨어진다. (104쪽)
    (3) Keep-Alive 헤더는 커넥션을 유지하기를 바라는 요청일 뿐이다. 클라이언트나 서버가 keep-alive 요청을 받았다고 해서 무조건 그것을 따를 필요는 없다. (106쪽)
    (4) 엔터티 본문이 정확한 Content-Length 값과 함께 멀티파트 미디어 형식(multipart media type)을 가지거나 청크 전송 인코딩(chunked transfer encoding)으로 인코드 되어야 함을 뜻한다. (107쪽)
    (5) 프락시는 같은 커넥션상에서 다른 요청이 오는 경우는 예상하지 못하기 때문에, 그 요청은 프락시로부터 무시되고 브라우저는 아무런 응답 없이 로드 중이라는 표시만 나온다. (110쪽)

추가 자료

W. Richard Stevens-TCP/IP Illustrated

느낀 점

OSI? TCP/IP? 웹 개발자, 특히나 프론트개발자에게 마냥 상관없는 주제이자 머나먼 주제라 생각했지만,
생각보다 이전에 들었었던 키워드들이 종종 등장해서 흥미롭게 읽었다.
성능 개선에 있어서 프론트엔드 개발자가 더 할 수 있는 게 없을지 고민하게 됐다.

특히나 파이프라인 커넥션에서의 요청 관련해서는 아는 것들이 왕왕 나와 재밌게 읽었다.

한 줄 요약

TCP 커넥션은 터널이고 교통 정리가 어떻게 되느냐에 따라 차가 안 밀릴 수 있다.

profile
프론트엔드 기술 학습 및 공유를 활발하게 하기 위해 노력합니다.

2개의 댓글

comment-user-thumbnail
알 수 없음
2022년 8월 20일
수정삭제

삭제된 댓글입니다.

1개의 답글