HTTP 최대 연결 수 - HTTP choedae yeongyeol su

이전 회사에서 개발할 때 있었던 일이었는데 나름대로 정리한 글이다. 우선 사건의 발단은 이러했다.

프런트의 한 페이지가 로딩이 너무 오래 걸린다는 이슈가 들어왔다. 그 페이지는 약 30개 정도의 API를 거의 동시에 요청한 후 response가 모두 도착했을 때 로딩이 끝나는 페이지였다. 처음 이 얘기를 듣고 떠오른 것은 요청한 API 중 response를 늦게 주는 API가 있어서 로딩이 오래 걸리고 있는 거 아닌가? 라는 생각이었다.

이 생각이 맞는지 확인을 하기 위해 개발자 도구를 열고 네트워크 쪽을 보니 역시나 요청한 API 중 마지막 response가 도착한 시각과 로딩 화면이 사라진 시각이 거의 일치했다. 근데 일치하긴 했는데 뭔가 이상했다. API를 요청한 시각은 거의 같게 찍힌 방면, response가 도착한 시각은 기하급수적으로 늘어졌기 때문이다.

해당 이미지는 따로 테스트 한 결과이다.

좀 더 자세히 보니 처음 요청한 6건 까지는 Waiting(TTFB, 녹색바) 그래프가 바로 그려진 방면, 그 외에 요청한 건은 전부 앞서 요청한 건들이 끝날 때까지 Stalled(회색바) 라는 그래프가 그려지고 있었다. 그 후 앞의 요청한 건이 끝나면 다음 6건까지Waiting(TTFB, 녹색바) 그래프가 그제야 그려지기 시작했고, 그 외에 건은 아까와 같이 계속 Stalled(회색바) 라는 그래프가 계속 그려지고 있었다.

즉 한 개의 API가 response까지 받는데 걸리는 시간이 5초라고 했을 때, 30개를 요청했다고 하면 처음 요청한 6건까지는 5초, 그다음 6건은 10초가 되었으며, 결국 마지막 6건은 25초나 걸리고 있었던 것이였다.

상위 6개의 속한 API중 하나의 상세화면이다. 그다음 6개의 속한 API중 하나의 상세화면이다.

기존에 Waiting(TTFB, 녹색바) 는 서버에서 응답을 받기까지 걸리는 시간이라고 알고 있었으나 Stalled(회색바)는 처음 본 상태 값이었다. 그래서 검색을 해보니 아래의 문서를 찾게 되었다.

문서를 훑어보니 Stalled(회색바)요청을 전송할 수 있게 되기까지 기다리는 데 소비한 시간이라고 나와있었다. 그렇다면 지금 브라우저에서는 처음에 요청한 6건을 제외하고는 서버에 요청도 하지 않았던 것이었다.

그럼 도대체 왜 요청하지 않았는가? 라는 의문이 들었는데 문서를 좀 더 보니 브라우저가 기다리는 이유도 같이 명시되어있었다. 그중 브라우저가 HTTP 1에서 각 출처마다 6개의 TCP 연결만 허용하기 때문에 요청이 보류되었습니다.라는 부분이 있는데 바로 이거였다. 크롬 브라우저는 HTTP 1 프로토콜로 동시에 6건까지만 요청이 가능했던 것이었다.

이렇게 일단 이유는 알게되었다. 하지만 지금은 다른 의문이 들기 시작했다. 우선 브라우저가 HTTP 1 이라는 부분은 즉 HTTP 1이 아닌 경우, 결과가 다르다는 건가? 각 출처마다 라는 것은 한 출처당 6개씩 출처를 바꾸면 동시에 처리할 수 있다는 건가? 그리고 마지막으로 이 조건은 모든 브라우저에 적용이 되는가? 였다.

Question 1, 모든 브라우저에 적용이 되는가?

그나마 최신 자료 위주로 찾아보니 다행히라 할지 모르겠지만 대부분의 최신 브라우저(크롬, 파폭, 사파리, 오페라)는 6개였다. 하지만 IE10은 10개, IE 11은 11개이고, 그 외 브라우저도 버전에 따라서 약간의 차이는 있다고 한다. (역시 익스플로러...)

Question 2, 각 출처마다?

이 또한 찾아보니 우선, 출처라는 것은 도메인을 의미하는 것이었다. 즉 한 도메인당 6개까지 동시 요청이 가능하단 이야기였고, 위 문서에서도 언급이 됐는데 다량의 요청을 좀 더 빠르게 처리하는 방법으로 도메인을 여러 개 두는 방법을 언급했다. 이를 도메인 샤딩이라고 한다.

Question 3, 브라우저가 HTTP 1?

사실 위에서 던진 질문의 순서와 답변을 반대로 적고 있었다. 이유는 자료를 찾다 보니 자료들이 서로 질문과 연결돼서였다. 답을 하자면 그렇다. HTTP 1에서만 이 조건이 적용되고 있었다. 새로 나온 HTTP 2에서는 구조가 개선되어 브라우저에서 동시 요청에 제한도 없다고 한다. (또한 위 문서에서 꼭 필요한 사항이 아니면 더이상 도메인 샤딩은 사용하지말고, HTTP2를 사용하는걸 권장하고 있다.)

결론

우선 회사에서 처리한 방법은 프런트에서 동시에 여러 개 날리는 로직을 백엔드로 가져왔고 그 대신 response에 데이터를 전부 가져갔는지 판단할 수 있는 필드를 추가하였다. 또한 프런트에서는 이 값을 확인하여 더 가져올 데이터가 있다면 서버에게 다시 요청하는 방식으로 수정하게 되었다.

참고로 동시 요청을 백엔드로 가져갔단 이야기는 사실 프런트에서 호출한 API는 다시 외부 API를 호출하는 API이다. 다만, 여러개를 날리는 이유는 각각 다른 외부 API를 호출하기 때문이었는데, 이를 프런트에서 동시에 호출하고 있었던 걸 백엔드 백그라운드에서 외부 API에 동시에 요청하고, 도착하는 순서대로 캐싱한다. 그리고 프런트에서 호출했을 때 이 캐싱된 데이터를 내려주는 방식으로 수정이 된 것이다.

또한 나는 프런트를 개발하면서 이 점을 처음 알았다. 애초에 저렇게 서버에 동시로 여러 개를 요청할 일이 별로 없었고, 있더라도 양이 많지 않았기 때문이었다.

하지만 곰곰히 생각해보니 꼭 그렇지 많은 않았다. 저렇게 많이 요청할 때가 있었기 때문이다. 바로 사이트를 접근했을 때이다. HTML을 내려받고 거기서 필요한 이미지나 js, css등 정적 파일을 불러오는 경우이다. 다만 이 경우 정적파일을 내려받는데 걸리는 시간이 크지 않기 때문에 체감이 될 정도로 느리다고 느끼지 못했던 거 같다.

마지막으로 이 일을 알아보면서 알게된 HTTP2에 대해서도 매우 관심을 가지게 됐다. 이제 대부분 최신 브라우저에서 지원을 하고, 혹시 지원하지 않는 브라우저도 웹서버에 설정만 하면 하위 프로토콜로 처리 할 수 있으며, 또한 이 프로토콜을 정적파일이 있는 서버에 적용하면 사용자들에게 조금이라도 더 빠르게 내려보낼 수 있기 때문이다. 그래서 차후에 HTTP2에 대해서도 한번 정리를 해 볼까 한다.

번외 (도메인 샤딩은 몇 개까지 가능할까?)

앞서 제목도 최대 연결 수 알아보기였는데 이 또한 도메인 샤딩으로 몇 개까지 동시 호출이 가능할지 궁금하여 찾아보니 따로 제한은 없고 컴퓨터나 브라우저에 성능에 따라서 달라질 수 있다고 하여 간단하게 실험을 해 보았다.

환경 (macbook pro 15 inch)
cpu: i7 4core 2.6GHz
ram: 16GB
browser: chrome 70

테스트 방식은 간단하게 1초 딜레이 후 리턴하는 API를 만들고, 프런트에서 서브도메인 1개당 6개 호출을 한 세트로, 수를 점점 늘려나갔다.

호출 수가 늘어날수록 전체적인 그래프가 오른쪽으로 기울기 시작하였으나, 눈에 확 띈 구간은 서브 도메인 43번의 5번째 API를 호출할 때였다. 처음에는 서버 문제인가 싶어 서버 한 대를 더 늘려서 서브도메인을 반으로 나눠 연결 후 다시 테스트를 해 보았으나 결과는 같게 나와 브라우저에 한계인걸로 생각하고 테스트를 종료했다.

결과는 이 컴퓨터에서 해당 브라우저로 약 256개를 동시에 호출이 가능한 거 같았다.

사실 이렇게 나온 게 정말 브라우저 문제인지 아니면 컴퓨터 설정에 문제인지는 모르겠지만 확실한 건 동시에 연결할 수 있는 수가 매우 많다는 것이며, 기존 HTTP1도 초기라면 몰라도 지금은 최소한 브라우저 성능에 의해 6개까지만 제한이 된 거는 아닌 거 같다는 점이였다.

이 정책을 설정하면 HTTP 1.1의 기본 연결 제한을 호스트당 6개에서 사용자가 선택한 제한(2개 - 128개)으로 변경할 수 있습니다.

이 정책 설정을 사용하면 Internet Explorer는 HTTP 1.1에 대해 선택된 연결 제한을 사용합니다.

이 정책 설정을 사용하지 않거나 구성하지 않으면 Internet Explorer는 HTTP 1.1의 기본 연결 제한을 사용합니다(호스트당 6개의 연결).

Internet Explorer 8 전의 버전에서는 HTTP 1.1의 기본 연결 제한이 2개였습니다.

지원: Internet Explorer 8.0 이상

최대 연결 수:

HTTP 최대 연결 수 - HTTP choedae yeongyeol su

Registry Hive HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
Registry Path Software\Policies\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER
Value Name iexplore.exe
Value Type REG_DWORD
Default Value 6
Min Value 2
Max Value 128

inetres.admx