다크 런치
Dark Launch
방법
사용자 화면에는 내보내지 않은 채 새 코드만 실제 요청으로 먼저 돌려 보는 배포 방식입니다.
등장 배경
내보내기 전에 하는 점검은 대부분 실제와 다른 조건에서 이뤄집니다. 테스트 환경의 데이터는 몇백 건인데 운영에는 몇백만 건이 쌓여 있습니다. 요청이 몰리는 시간대도, 사람들이 실제로 넣는 이상한 입력값도 재현되지 않습니다.
그래서 배포는 오래 이런 모양이었습니다. 검수를 통과한 기능을 새벽 세 시에 올리고 아침에 문의가 들어오는지 지켜봅니다. 문제가 나면 그때 되돌립니다. 되돌리기까지 몇 시간 동안은 모든 사용자가 그 문제를 겪습니다.
화면은 그대로 두고 안쪽 구조만 갈아 끼우는 작업에서 특히 답답했습니다. 저장 방식을 바꾸거나 검색 엔진을 교체하는 일은 사용자가 보기에 아무 변화가 없어야 하는데, 정작 제대로 도는지는 실제 트래픽을 받아 보기 전에 알 수 없었습니다.
다크 런치는 이 순서를 뒤집습니다. 사용자에게 여는 일과 코드를 돌리는 일을 떼어 놓고, 열지 않은 채 돌려 보는 구간을 먼저 만듭니다. 점진적 출시가 노출 범위를 조금씩 넓혀 가는 방식이라면 다크 런치는 그 범위가 아직 0인 첫 구간입니다.
사용 절차
실제 요청이 들어올 때 옛 경로와 새 경로를 함께 돌리되, 사용자에게 돌려주는 답은 옛 경로 것만 쓰고 새 경로의 결과는 기록해 비교합니다. 다섯 단계입니다.
- 스위치를 심습니다. 코드를 배포한 채 기능만 켜고 끌 수 있게 해 주는 피처 플래그를 먼저 넣습니다. 새 경로를 돌릴지 말지가 이 스위치에 걸립니다.
- 두 경로를 같이 실행합니다. 요청 하나가 들어오면 옛 검색 엔진과 새 검색 엔진에 같은 질의를 동시에 보냅니다.
- 내보내는 답은 옛 경로 것입니다. 새 경로가 내놓은 값은 화면에 쓰지 않고 로그에만 남깁니다. 이 단계에서 새 경로가 틀린 답을 내도 사용자는 알지 못합니다.
- 두 결과를 대조합니다. 답이 다른 건수, 새 경로의 응답 시간, 오류율을 봅니다. 기준은 시작 전에 정합니다. 예를 들어 하루 동안 불일치 0.1퍼센트 미만, 응답 시간이 옛 경로의 1.2배 이내처럼 숫자로 적어 둡니다.
- 기준을 채우면 스위치를 켭니다. 여기서부터는 소수에게 실제로 열어 보는 카나리 릴리스로 넘어가고, 이상이 없으면 노출 비율을 단계적으로 올리는 퍼센트 롤아웃이 이어집니다.
4번이 성립하려면 밖에서 안을 볼 수 있어야 합니다. 시스템 안에서 무슨 일이 벌어지는지 밖에서 알 수 있는 정도를 관측성이라고 하는데, 이게 갖춰지지 않은 팀은 새 경로를 며칠 돌려 놓고도 무엇이 어긋났는지 모릅니다. 불일치가 난 요청이 무엇이었는지까지 남겨야 원인을 찾습니다.
기간은 보통 며칠에서 한두 주입니다. 월말 정산처럼 특정 시점에만 몰리는 부하가 있다면 그 시점을 한 번 지나 보기까지가 이 단계입니다.
적합한 상황과 한계
잘 맞는 자리는 셋입니다.
- 화면은 그대로 두고 안쪽만 바꾸는 작업. 옛 경로와 새 경로가 같은 답을 내야 하는 상황이라 대조할 정답이 이미 있습니다.
- 부하를 미리 재야 하는 작업. 실제 요청량을 그대로 받으므로 부하 테스트로 흉내 낸 것보다 정확합니다. 만들어 낸 요청은 대개 실제보다 규칙적입니다.
- 되돌리기 어려운 변경. 데이터 저장 구조를 바꾸는 일처럼 한 번 나가면 롤백이 무거운 작업은 열기 전에 확인할 수 있는 구간이 길수록 좋습니다.
한계도 분명합니다.
- 화면이 바뀌는 기능에는 쓸 수 없습니다. 사용자가 새 버튼을 누르는지 보려면 결국 보여 줘야 합니다. 이때는 다크 런치가 아니라 소수에게 여는 방식으로 바로 갑니다.
- 바깥에 영향을 남기는 동작은 두 번 실행하면 안 됩니다. 결제 승인이나 메일 발송을 양쪽에서 다 돌리면 사용자는 돈이 두 번 빠져나가는 것을 봅니다. 이런 동작은 새 경로에서 실제 호출 대신 호출했을 값만 기록하도록 막아 둡니다.
- 비용이 듭니다. 두 경로를 동시에 돌리니 서버 부담이 늘고, 분기가 들어간 코드는 읽기 어려워집니다. 그래서 스위치를 심을 때 치울 날짜를 함께 적어 둡니다. 문제가 생겼을 때 기능만 즉시 끄는 킬 스위치와 달리 이쪽은 성공한 뒤에 치우는 정리 작업입니다.
실무 용례
"일단 다크 런치로 일주일 돌려 보고 불일치 건수 보고 결정하죠."
새 경로를 열지 말지를 감이 아니라 대조 결과로 정하자는 제안입니다.
"이건 메일이 나가는 동작이라 다크 런치 못 해요."
두 번 실행하면 사용자 쪽에 실제 영향이 가는 작업이라는 뜻입니다.
"다크 런치 중인데 새 쪽 응답이 세 배 느려요. 켜면 안 되겠는데요."
기준을 못 채웠으니 다음 단계로 넘기지 말자는 판단입니다.
페이지덱이 문서 검색을 새 엔진으로 옮길 때 이 방식을 썼습니다. 태오가 검색 요청 하나마다 옛 엔진과 새 엔진에 같은 질의를 보내되 화면에는 옛 엔진의 결과만 내보내도록 했습니다. 새 엔진의 결과는 상위 10건이 얼마나 겹치는지와 응답 시간만 기록했습니다.
첫 이틀은 겹침이 60퍼센트대였습니다. 한글 문서 제목을 쪼개는 방식이 달라서였고, 사용자는 그동안 아무것도 느끼지 못했습니다. 설정을 고치고 나흘을 더 돌려 겹침이 97퍼센트를 넘은 뒤에 지현이 사내 계정부터 스위치를 켜자고 정했습니다.
흔한 오해
사용자에게 안 보이니까 안전하다고 읽는 경우가 가장 많습니다. 화면에 나가지 않는다는 말이 영향이 없다는 말처럼 들리기 때문입니다. 하지만 새 경로도 같은 데이터베이스를 읽고 같은 서버 자원을 씁니다. 요청량이 두 배가 되면서 응답이 전체적으로 느려지거나, 새 경로가 잘못 짠 질의로 데이터베이스를 붙잡아 옛 경로까지 멈추는 일이 실제로 생깁니다. 다크 런치에도 스위치가 필요하고, 숫자가 나빠지면 그 자리에서 끕니다.
테스트를 대신한다고 읽는 오해도 잦습니다. 실제 데이터로 돌려 보니 앞 단계는 건너뛰어도 될 것처럼 보입니다. 그런데 이 단계가 잡아 주는 것은 실제 조건에서만 드러나는 문제뿐입니다. 정해진 입력에 정해진 답이 나오는지 같은 기본 확인은 여전히 앞에서 해야 하고, 그걸 빼고 오면 불일치 목록이 수천 건씩 쌓여 무엇이 진짜 문제인지 가려낼 수 없게 됩니다.
자주 헷갈리는 용어
| 용어 | 사용자에게 보이는가 | 다크 런치와의 차이 |
|---|---|---|
| 소프트 런치 | 보입니다 | 기능은 열어 두고 홍보만 하지 않는 출시입니다. 조용하다는 점이 같아 보이지만 소프트 런치의 사용자는 실제로 그 기능을 씁니다 |
| 카나리 릴리스 | 일부에게 보입니다 | 소수에게 진짜로 열어 반응을 봅니다. 다크 런치 바로 다음 단계이고, 노출이 0이냐 1퍼센트냐가 둘을 가릅니다 |
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16