“같은 요청 하나도, 어디에서 멈췄느냐에 따라 전혀 다른 문제처럼 보일 수 있어요.”CDN, Cache, 그리고 Edge Delivery에서는 사용자 가까이에 복사본을 두면 왜 더 빨라질 수 있는지 봤어요. 근데요, 여기까지 보고 나면 이런 궁금증이 생기죠.
“좋아요. DNS도 알고, TLS도 알고, 프록시도 알고, CDN도 알겠어요. 근데 실제로 느린 요청 하나가 생기면, 이제 어디부터 봐야 하죠?”바로 그 질문에 답하는 글이 이번 글이에요. 이번에는 브라우저에서 시작한 요청 하나를 끝까지 따라가면서, 어느 구간에서 시간이 쓰이고, 어느 지점에서 문제가 생길 수 있는지 를 한 장의 흐름으로 묶어볼게요. 참고로 여기서는 특정 회사의 설정 화면이나 특정 브라우저 버튼 이름보다, 어떤 체크포인트를 어떤 순서로 보면 덜 헷갈리는지 에 집중할게요.
요청 하나를 체크포인트로 따라가요
이번에는 큰 서점에 책 한 권을 주문한다고 상상해볼까요?- 먼저 서점 이름으로 전화번호를 찾고,
- 실제로 전화가 연결되고,
- 진짜 그 서점이 맞는지 확인하고,
- 주문은 대표 안내 데스크가 먼저 받고,
- 가까운 지점에 책이 있으면 거기서 바로 꺼내주고,
- 없으면 본사 창고까지 다시 확인하겠죠.
핵심은 이거예요.
요청 하나가 항상 끝까지 똑같은 길을 다 가는 건 아니에요.
어떤 요청은 캐시에서 바로 끝나고,
어떤 요청은 오리진까지 깊숙이 들어가야 하죠.
요청 하나를 따라갈 때는 체크포인트로 보면 쉬워요
End-to-End Request Debugging을 어렵게 느끼는 가장 큰 이유는, 머릿속에 너무 많은 이름이 한꺼번에 떠오르기 때문이에요. DNS, TCP, TLS, 프록시, CDN, 캐시, 오리진… 이걸 전부 따로 외우려고 하면 오히려 더 헷갈려요. 그래서 이렇게 보면 훨씬 쉬워져요. “이 요청은 지금 어느 체크포인트까지 갔지?” 여기서 한 가지 먼저 짚고 갈게요. 이 순서는 모든 서비스가 실제로 똑같은 장비 순서로 서 있다 는 뜻이 아니라, 요청을 읽을 때 덜 헤매기 위한 디버깅 체크리스트에 더 가까워요. 현실에서는 CDN이 가장 앞에 설 수도 있고, TLS를 엣지에서 끝낼 수도 있고, 프록시와 로드 밸런서 역할이 한곳에 겹쳐 있을 수도 있거든요. 이 그림이 좋은 이유는, 속도가 느리거나 에러가 났을 때 어디에서 멈췄는지 질문하기 쉬워지기 때문이에요. 예를 들면:- DNS도 못 끝났다면 아직 서버는 만나지도 못한 거고,
- TLS에서 경고가 났다면 앱 코드까지 가기 전에 막힌 거고,
- 캐시에서 바로 끝났다면 오리진은 바쁘지 않았을 수 있어요.
먼저, 어떤 증상인지부터 나눠볼까요?
현실에서는 “느려요” 한마디로 끝나는 경우가 많죠. 근데 사실 그 안에는 전혀 다른 종류의 문제가 섞여 있을 수 있어요. 그러니까 첫 질문은 “왜 느리지?” 가 아니라, “어떤 종류로 이상하지?” 예요. 이 질문 하나만 잘해도, 처음부터 앱 코드만 뒤지거나 반대로 네트워크만 의심하는 실수를 꽤 줄일 수 있어요.DNS에서 이미 막힐 수도 있어요
DNS는 어떻게 이름을 IP 주소로 바꿀까요?와 DNS 레코드는 왜 종류가 여러 갈래일까요?에서 봤던 것처럼, 브라우저는 먼저 이 이름이 어느 주소로 가야 하는지 알아내야 해요. 이 단계에서 생길 수 있는 문제는 생각보다 단순해요.- 이름 자체를 못 찾음
- 오래된 주소를 봄
- 조회가 너무 느림
- 가야 할 대상이 잘못 연결됨
- 서버 로그에는 아무것도 안 남을 수도 있고,
- 애플리케이션은 억울하게 욕을 먹을 수도 있어요.
연결은 됐는데 TLS에서 멈출 수도 있어요
이름을 주소로 잘 찾았다고 해서 끝은 아니에요. 이제는 실제로 연결을 열고, HTTPS라면 신뢰할 수 있는 상대인지 확인해야 하거든요. TCP 3-way handshake에서 본 연결 열기와, TLS, SSL, 인증서에서 본 확인 과정이 여기서 다시 만나요. 여기서는 TLS가 병목이 될 수 있다는 감각까지만 잡고 갈게요. 메시지 순서는 TLS 1.3 핸드셰이크, 인증서 경고의 원인은 인증서 체인과 신뢰 오류에서 더 구체적으로 이어서 볼 수 있어요. 이 단계에서 자주 나오는 장면은 이런 식이에요.- DNS는 끝났는데 연결이 한참 안 열림
- 연결은 열리는데 인증서 경고가 뜸
- HTTPS 협상이 느려서 첫 응답이 늦게 시작됨
서버 앞단은 요청을 대신 받고 나눠 보내요
Proxy, Reverse Proxy, 그리고 Load Balancer에서 봤던 것처럼, 현실의 서비스는 브라우저가 곧바로 안쪽 앱 서버와 1:1로 말하는 그림이 아닐 때가 많아요. 중간에 리버스 프록시가 먼저 받고, 로드 밸런서가 어느 서버로 보낼지 고를 수도 있어요. 이 감각이 왜 중요하냐면, 에러가 보여도 그 에러를 누가 만들었는지 가 달라질 수 있기 때문이에요.- 앞단에서 바로 막았는지
- 뒤 서버로 보내긴 했는데 거기서 실패했는지
- 뒤 서버가 아파서 다른 서버로 우회했는지
캐시에서 끝났는지, 오리진까지 갔는지가 갈려요
CDN, Cache, 그리고 Edge Delivery까지 보고 나면, 이제 요청을 볼 때 반드시 하나 더 떠올려야 해요.“이 응답은 가까운 복사본에서 끝난 걸까요, 아니면 원본 서버까지 갔을까요?”이 차이는 체감 속도에도 크고, 원인 파악에도 아주 커요.
- 캐시 히트면 엣지나 중간 캐시에서 바로 끝날 수 있고,
- 캐시 미스면 오리진까지 다시 가야 하고,
- 오래된 복사본 문제라면 내용은 보이는데 이상하게 낡아 보일 수도 있어요.
- 이번엔 캐시 히트였나 미스였나
- 지난번과 같은 경로였나
- 응답 헤더에 캐시 흔적이 남아 있나
- 캐시가 오래된 사본을 보여준 건 아닌가
Age, X-Cache, Cache-Status, Server-Timing 같은 헤더는
환경에 따라 있을 수도 있고 없을 수도 있어요.
중요한 건 이름을 외우는 것보다, “중간에서 끝났는지” 를 읽으려는 태도예요.
어떤 환경은 캐시 상태를 친절하게 보여주고, 어떤 환경은 거의 안 보여줘요. 그러니까 헤더는 좋은 단서이긴 하지만, 없다고 해서 바로 결론을 내리면 안 돼요.
오리진까지 갔는데도 느릴 수 있어요
여기까지 왔다면 이제 진짜 원본을 만드는 쪽까지 간 거예요. 이 단계에서는 비로소 이런 질문이 힘을 가지기 시작해요.- 데이터베이스가 느린가?
- 외부 API를 오래 기다리나?
- 앱이 너무 많은 일을 한 번에 하나?
- 오류는 났지만 앞단이 대신 다른 형태로 보여주고 있나?
근데 왜? 굳이 이런 순서로 따라가야 할까요?
그냥 눈에 보이는 에러 메시지 하나 보고 찍어가면 안 될까요? 사실은 위험해요. 왜냐하면 같은 증상도 전혀 다른 이유로 생길 수 있기 때문이죠.1. “느리다”는 말은 너무 넓어요
DNS가 느린 건지, TLS 협상이 느린 건지, 캐시 미스라서 오리진까지 간 건지, 오리진 처리 자체가 느린 건지… 겉으로는 전부 그냥 “느리다” 로 보일 수 있어요.2. 중간자가 많을수록 책임 구간도 나뉘어요
브라우저와 앱 서버 사이에는 생각보다 많은 중간자가 있을 수 있어요. 그래서 “서버가 이상하다”는 말만으로는 너무 많은 가능성을 한꺼번에 가리키게 돼요.3. 체크포인트 순서가 있어야 엉뚱한 곳에서 헤매지 않아요
DNS도 안 된 요청을 들고 애플리케이션 로그를 몇 시간 보는 건 너무 억울하잖아요. 반대로 오리진이 진짜 느린데, 계속 인증서나 DNS만 만지는 것도 빗나간 수고고요. 즉, 이 순서는 이론을 멋있게 늘어놓으려는 게 아니라, 덜 헤매기 위한 디버깅 동선에 가까워요.그럼 진짜 요청 하나를 같이 따라가볼까요?
이번에는 브라우저가 아래 요청을 보낸다고 상상해볼게요.https://shop.example.com/images/product-42.jpg
이 요청은 어떤 날엔 빠르고,
어떤 날엔 느리고,
어떤 날엔 오래된 이미지처럼 보일 수도 있어요.
그럴 때는 이렇게 따라가면 돼요.
이 흐름을 디버깅 언어로 바꾸면 이래요.
- 주소는 잘 찾았나?
- 연결과 TLS는 무사했나?
- 앞단에서 막히진 않았나?
- 캐시에서 끝났나, 오리진까지 갔나?
- 오리진까지 갔다면 거기서 오래 걸렸나?
- 브라우저에서 본 건 브라우저 기준의 기다림이고,
- 중간 캐시에서 본 건 캐시 기준의 기다림이고,
- 서버 근처에서 본 건 오리진 기준의 기다림일 수 있어요.
처음 볼 때는 이런 단서부터 챙기면 좋아요
처음부터 모든 로그와 모든 패킷을 한꺼번에 들여다보려 하면 금방 지쳐요. 그래서 초반엔 이 정도만 챙겨도 충분해요.- 요청이 실패한 위치에 가까운 증상
- 이름 해석 실패인지, 인증서 경고인지, 502/503인지, 그냥 느린지
- 응답이 오기 전 시간이 길었는지, 응답 본문이 내려오는 시간이 긴지
- 첫 바이트가 늦은 건지, 내려받는 몸집이 큰 건지 감이 달라져요
- 캐시 흔적이 보이는지
- 히트인지 미스인지, 오래된 사본인지
- 같은 문제를 다른 위치에서도 똑같이 보는지
- 브라우저만 느린지, 서버 쪽에서도 느린지
- 재전송이나 경로 문제 단서가 있는지
- TCP 재전송과 신뢰성이나 ICMP, Ping, 그리고 Traceroute에서 봤던 감각이 여기서 다시 도움돼요
자, 정리해볼까요?
- End-to-End Request Debugging 은 요청 하나가 DNS → 연결 → TLS → 서버 앞단 → 캐시 → 오리진 중 어디까지 갔는지 따라가는 일이에요.
- 같은 “느림” 이라도 DNS, TLS, 캐시 미스, 오리진 처리처럼 원인은 전혀 다를 수 있어요.
- 그래서 첫 질문은 “왜 느리지?” 보다 “어느 체크포인트까지는 무사했지?” 에 가까워요.
- 캐시에서 바로 끝난 요청과 오리진까지 깊게 들어간 요청은 체감 속도도, 원인 파악 방식도 달라요.
- 중요한 건 특정 회사 화면을 외우는 게 아니라, 요청이 어디에서 멈췄고 그걸 어디에서 관찰했는지 차근차근 구분하는 감각이에요.
다음 글 예고
여기까지가 기본편에서 그린 큰 흐름이에요.“이제 실제 캡처나 브라우저 화면에서는 이 흐름을 어떻게 읽어야 할까요?”다음 단계에서는 패킷 캡처, 브라우저 타이밍, 캐시 헤더, 장애 상황처럼 장면 하나를 골라 더 깊게 들어가면 돼요. 심화편 입구에서 궁금한 장면부터 이어서 읽어보세요.