서버시간과 폰 시계
큰 예매 전에 많은 사람이 서버시간 페이지를 열어두고 밀리초까지 흘러가는 시계를 봅니다. 정밀해 보이죠. 그 숫자가 실제로 무엇인지 알아두면 좋습니다. 그 숫자가 주는 확신이 실제 정확도보다 크기 때문입니다.
그 숫자는 어디서 오나
거의 모든 서버시간 도구는 같은 방식으로 동작합니다. 어떤 사이트에 HTTP 요청을 보내고, 응답의 Date 헤더를 읽고, 로컬 시계와 비교합니다. 그 차이가 오프셋이고, 그걸 기기 시계에 더해서 보여줍니다.
여기에 한계가 세 가지 있습니다.
- 헤더의 해상도는 1초입니다. HTTP
Date필드는 정수 초 단위로 규정돼 있습니다. 밀리초가 애초에 들어있지 않아요. 화면에 보이는 밀리초 자리는 받은 게 아니라 추정한 값입니다. - 왕복 시간은 아는 게 아니라 추정합니다. 도구는 요청에 걸린 시간을 재고 그 지연이 가는 길과 오는 길에 반씩 나뉘었다고 가정합니다. 모바일 네트워크에서는 자주 그렇지 않고, 50ms 정도의 비대칭은 평범합니다.
- 재고 나면 시계는 흐릅니다. 폰의 크리스털은 드리프트가 있고, 10분 전에 잡은 오프셋은 지금의 오프셋이 아닙니다. 좋은 도구는 드리프트를 추정하지만, 그 추정 자체도 불확실합니다.
이걸 다 합치면 현실적인 정확도는 잘해야 수십 ms 수준이지, 화면의 소수점 세 자리가 아닙니다. 여전히 쓸모는 있어요. 다만 표시가 암시하는 것과는 다릅니다.
더 큰 문제: 어느 서버인가
측정이 완벽해도 질문이 틀렸습니다. 당신이 잰 건 그 페이지를 돌려준 웹 서버의 시계입니다. 당신의 클릭이 유효한지를 판정하는 건 다른 기계예요. 예매 API, 대기열 서비스, 재고 데이터베이스. 큰 사이트는 이걸 별도 인프라에서 돌리고, 그 시계들이 당신이 잰 시계와 같아야 할 이유가 없습니다.
이론적인 얘기가 아닙니다. 서버시간 앱 사용자들은 몇 달 동안 정확하던 앱이 어느 날 특정 사이트에서 딱 1초 어긋났다는 후기를 꾸준히 남깁니다. 그 사이트가 버튼을 처리하는 서버를 바꿨기 때문이에요. 앱이 고장난 게 아닙니다. 앱이 재고 있던 대상이 애초에 중요한 대상이 아니었던 겁니다.
유일하게 옳은 서버시간이란 건 없습니다. 대체로 맞지만 정확히 같지는 않은 시계들의 무리가 있고, 우리는 그중 하나만 볼 수 있을 뿐입니다.
그래도 서버시간이 쓸모 있는 경우
공정하게 말하면 도움이 되는 상황도 있습니다.
- 내 폰 시계가 진짜로 틀린 경우. 요즘 안드로이드에선 드물지만, 약한 네트워크나 해외 이동 후에 생깁니다.
- 페이지와 버튼이 명백히 같은 서버인 작은 사이트에서의 예매.
- 1초씩 어긋나 있진 않은지 대략 확인하고 싶을 때. 그 정도는 확실히 해줍니다.
못 하는 건 내 클릭을 받아줄 그 기계를 밀리초 단위로 보여주는 일입니다. 할 수 있다고 여기는 순간, 정작 중요한 그날에 조용히 틀린 숫자를 믿게 됩니다.
대신 무엇을 할까
오차 요인을 크기와 통제 가능성으로 줄 세워 보세요. 시계 오프셋은 보통 수백 ms이고 부분적으로 통제 가능합니다. 내 반응속도는 250~350ms이고 통제 가능합니다. 네트워크 지연은 30~100ms이고 통제 불가능합니다. 클릭 이후 — 보안문자, 좌석 선택 — 는 초 단위이고 전부 통제 가능합니다.
노력을 쓸 순서가 바로 나옵니다.
- 클릭 이후의 초를 연습하세요. 통제 가능한 것 중 가장 큰 덩어리이고, 거의 아무도 연습하지 않는 부분입니다.
- 내 반응속도를 알고 딱 그만큼 앞당겨 움직이세요. 250ms 이상의 값어치이고, 어떤 서버에도 의존하지 않습니다.
- 내 시계를 점검하세요. 여기에 서버가 필요하지 않습니다. 다른 화면에 정확한 기준 시계를 띄우고 세 번 맞춰 탭하면, 그 중앙값 오프셋은 HTTP 헤더가 주는 것 못지않고 10초면 끝납니다.
- 그다음에 원한다면 서버시간을 보세요. 진실의 근거가 아니라 교차 확인용으로.
정직한 요약
밀리초 표시는 측정의 보증이 아니라 디자인 선택입니다. 내가 실제로 통제할 수 있는 시계는 내 것이고, 내가 실제로 줄일 수 있는 지연은 신호와 내 손 사이의 것입니다. 나머지는 전부 남의 인프라이고, 숫자를 아무리 오래 봐도 바뀌지 않습니다.
탭제로는 일부러 반대 방향을 택했습니다. 서버시간을 아예 받아오지 않아요. 기기 시계에, 정확한 시계에 맞춰 세 번 탭해서 직접 정한 오프셋을 더해 보여주고, 내가 측정한 반응속도만큼 카운트다운 신호를 앞당깁니다. 아무것도 폰 밖으로 나가지 않고, 연결 없이도 동작합니다.