빠르게 하려고 Cloudflare로 가려다 Cloudflare에서 나왔다

백엔드 전체를 Cloudflare로 옮길까 물었다. 옮기기 전에 재보니 백엔드를 한 번도 안 부르는 페이지와 정적 PNG가 똑같이 0.47초였다. 무료 플랜이 요청 5건 중 1건을 죽이고 있었고, 결론은 정반대 방향이었다

공시 요약 서비스의 웹은 Cloudflare 무료 플랜에서 돌고, 백엔드와 데이터베이스는 Railway에 있다. 한국에서 느린 게 서버가 다 해외라 그런가 싶었고, 그렇다면 전부 엣지로 옮기면 되겠다고 생각했다. 옮기기 전에 재 봤더니 숫자가 정반대를 가리켰다.

하려던 것

밤 11시 41분에 물었다.

다른 세션에서 속도를 더 빠르게 하려고 하다 보니, Cloudflare로 백엔드 전체 전환을 생각해 봤는데 되려나? Railway 월 20달러짜리 쓰고 있어.

공시 요약 서비스의 웹은 Cloudflare Workers 무료 플랜에서 SSR로 돌고, 백엔드와 DB는 Railway에 있다. 서버가 다 해외라 느릴 수밖에 없나 싶었고, 그렇다면 전부 CDN 엣지로 옮기면 빨라지지 않을까 했다. 같은 밤 의정활동 트래커 세션에서도 같은 질문을 던지고 있었다.

어떻게 시켰나

에이전트가 옮기기 전에 병목부터 재자고 했다. 세 가지를 같은 조건으로 쟀다. 백엔드를 여러 번 부르는 홈, 백엔드를 0회 호출하는 개인정보 방침 페이지, 워커도 백엔드도 안 거치는 정적 PNG.

셋이 똑같이 0.47초였다. 연산이 0이어도 나오는 숫자였다. 백엔드를 옮겨도 이 0.47초는 그대로다.

측정 자체도 한 번 틀렸다. 커스텀 도메인이 CF 프록시 뒤라 처음 잰 값은 프록시를 포함한 값이었고, 대상을 갈라 다시 쟀다.

어디서 막혔나

원인은 둘이었다.

무료 존은 서울 PoP를 못 탄다. 한국에서 connect가 144ms였다. 같은 Cloudflare 위의 다른 사이트는 7ms. 무료 존의 요청이 캘리포니아로 가고 있었다. 유료 플랜 얘기가 나왔는데 답은 “싫어, 이 정도로 트래픽이 나오지도 않잖아”였다.

무료 플랜 CPU 10ms를 SSR이 못 지킨다. CPU p50이 23.9ms였다. 예산의 2.4배다. 초과한 요청은 Error 1102로 죽는다. 3일치 집계가 성공 85,413건에 리소스 초과 20,890건, 19.4%였다. 요청 5건 중 1건이 조용히 죽고 있었다.

이게 갑자기 나빠진 데엔 이유가 있었다. 며칠 전 사이트맵을 100건에서 172,433건으로 늘렸다. 크롤이 두 배가 되자 실패율이 5.9%에서 23.3%로 네 배가 됐다. 검색에 잘 보이려고 한 일이 검색 크롤러를 죽이고 있었다.

어떻게 풀었나

결론이 정반대로 나왔다. 백엔드를 CF로 옮기는 게 아니라 웹을 CF에서 빼서 Railway로.

비용부터 걱정했다. “무료로 쓰던 걸 Railway로 넘기면 돈이 훨씬 나올 것 같은데.” 추정은 월 25.32달러에 6달러 추가였다. 옮기고 재니 웹 컨테이너 idle RAM이 63MB라 실측 4달러였다.

옮기는 과정에서 함정 다섯을 밟았다. railpack이 Dockerfile을 이겼다. Railway가 PORT를 주입해서 웹은 8080인데 백엔드도 8000이 아니라 8080이라 502와 ECONNREFUSED가 났다. 빈 DSN이 ?? 연산자를 통과해 Sentry가 조용히 꺼졌다. Next의 데이터 캐시가 되살아나 사이트맵이 낡았다. 개인정보 방침에 “7일 전 공고” 게이트를 넣었다가 과하다고 스스로 되돌렸다.

옮기고 나서 connect는 181ms에서 35ms로, TTFB는 0.51초에서 0.21초로 내려갔다. 다음 날 아침 워커를 지웠다.

배운 점