Cloudflare를 붙였는데 한국에서 오히려 느려진 이유
한국 사용자를 대상으로 운영 중인 데모 사이트에서 응답 지연을 점검했습니다. 도메인은 Cloudflare 프록시를 거치게 해뒀고, 원본 IP와 오리진을 보호하기 위해 켜둔 상태였습니다. 그러다 사이트를 손보는 중에 "버튼이 한 박자 늦게 눌리는 것 같다"는 얘기가 나왔고, 확인해 보니 앱 코드가 아니라 이 프록시 경로가 지연의 가장 큰 덩어리였습니다.
먼저 curl로 페이지별 응답 시간을 재봤습니다.
/dashboard TTFB 1.52s
/orders TTFB 1.03s
/tickets TTFB 1.03s
/leads TTFB 0.82s대시보드가 1.5초인 건 이해가 갔습니다. DB 질의가 40번 나가는 무거운 화면이라 그러려니 했습니다. 이상한 건 가벼운 페이지들이었습니다. 질의가 몇 개 안 되는 화면도 1초 안팎이 나왔습니다. 페이지마다 편차가 있다기보다, 모든 페이지에 0.8초쯤 되는 바닥값이 깔려 있는 모양새였습니다.
처음에는 오리진 서버의 성능을 의심했습니다. 전에 콜드 스타트로 502를 겪은 적이 있어서 그쪽부터 봤는데, 서버가 힘들면 무거운 페이지일수록 더 느려져야지 이렇게 균일한 상수가 붙는 건 설명이 안 됐습니다. 이런 모양의 지연은 대개 코드가 아니라 경로에 있습니다.
cf-ray 세 글자로 끝난 확인
응답 헤더를 열어봤습니다.
$ curl -s -o /dev/null -D - https://cp.duolabs.co.kr/tickets
server: cloudflare
cf-cache-status: DYNAMIC
cf-ray: ........-LAXcf-ray 헤더 끝의 세 글자가 그 요청을 처리한 Cloudflare 엣지의 공항 코드입니다. LAX, 로스앤젤레스였습니다. 한국 사용자의 요청이 LA 엣지를 경유한 뒤 오리진으로 전달되고, 응답도 같은 경로를 거쳤습니다. 태평양을 두 번 건너면 왕복으로 수백 ms가 그냥 사라집니다. 모든 페이지에 붙어 있던 0.8초의 정체가 대충 맞아떨어졌습니다.
Cloudflare는 서울에도 엣지가 있는데 왜 LAX로 갔는지는 확인하지 못했습니다. 무료 플랜 트래픽은 가까운 PoP 대신 먼 PoP로 배정되는 경우가 있다고 알려져 있지만, 배정 기준이 공개돼 있지 않아서 어디까지나 추정입니다. 다만 cf-ray가 LAX를 가리키는 동안에는 앱을 아무리 다듬어도 이 몫은 줄지 않는다는 것만은 분명했습니다.
선택지 정리
세 가지쯤으로 정리했습니다. 프록시를 끄고 DNS만 쓰면 경로 문제는 사라지지만 오리진 서버의 원본 IP가 그대로 노출됩니다. Argo 같은 유료 라우팅을 쓰는 방법도 있습니다. 아니면 경로는 그대로 두고 앱 쪽에서 체감을 줄이는 방법이 있습니다.
저는 일단 세 번째부터 했습니다. 스켈레톤과 클릭 피드백을 정리하는 쪽인데, 이 얘기는 글이 따로 있습니다. 프록시를 어떻게 할지는 아직 결정하지 못했습니다. 운영 중인 오리진의 IP 노출은 피해야 했습니다.
같은 증상을 만나면 앱 코드를 열기 전에 curl 한 줄부터 쳐보는 게 순서인 것 같습니다. 모든 페이지에 비슷한 크기로 붙는 지연은 코드보다 경로를 먼저 의심하라는 신호이고, cf-ray 세 글자면 확인이 끝납니다.
같은 작업에서 겪은 다른 문제:
함께 읽기
- Cloudflare 무료 플랜과 한국 엣지: TTFB 1초의 원인 분해데모 사이트 하나가 느렸습니다. 첫 바이트까지 1초가 걸렸습니다. 대시보드를 여는 화면이라 무겁긴 한데, 그래도 1초는 이상했습니다. 앱을 뜯어볼 생각으로 시작했다가, 결국 앱은 한 줄도 안 고쳤습니다.
- 한국에서 Cloudflare 엣지가 서울이 아닐 때: 무료 플랜의 POP 배정이미지 엣지 캐시를 손보고 나서 얼마나 빨라졌는지 재고 있었습니다. 캐시에서 나오면 156ms, 오리진까지 가면 622ms. 4배 차이니까 좋아하고 있었는데, 156ms라는 숫자가 자꾸 걸렸습니다.
- Cache-Control: immutable인데 왜 Cloudflare는 계속 DYNAMIC이었을까요?CDN을 붙이고 응답 헤더에 긴 캐시 시간을 설정했는데도 CF-Cache-Status가 계속 DYNAMIC으로 표시되는 경우가 있습니다. 저희도 파일 제공 기능을 점검하면서 같은 상황을 만났습니다.
- 새 서브도메인이 특정 브라우저에서만 안 열릴 때: DNS 캐시 점검법새 서브도메인을 추가한 직후 “Safari에서는 열리는데 Chrome에서는 안 열린다” 같은 일이 생길 수 있습니다. 이럴 때 바로 서버 장애나 DNS 설정 오류라고 판단하기 쉽지만, 실제 원인은 로컬 또는 브라우저 DNS 캐시인 경우가 많습니다.
- 배포하면 CSS가 404: stale-while-revalidate 함정"모바일에서 사이트가 이상해요."