같은 커밋인데 서버와 내 컴퓨터에서 글 목록 순서가 달랐다
한눈에 답변
인사이트 목록 페이지의 구조화 데이터 속 글 목록이 데이터베이스가 반환하는 순서를 그대로 쓰고 있었다. 정렬이 동점 처리 규칙만 없는 게 아니라 정렬 자체가 없었다. 같은 커밋을 리눅스 서버와 윈도우 로컬 환경에서 각각 빌드해 비교하니 19건 중 13건의 순서가 서로 달랐다. 화면에는 보이지 않는 값이라 놓치기 쉬웠지만, 이것도 매번 같은 결과를 내야 하는 빌드 산출물이었다.
무엇을 확인하다 발견했나
인사이트 목록 페이지가 내보내는 구조화 데이터 안에는 글 목록 배열이 들어 있는데, 이 배열이 데이터를 읽어 온 순서를 그대로 쓰고 있었다. 정렬 함수 자체가 아예 적용돼 있지 않았다.
실제로 순서가 흔들리는지 어떻게 확인했나
같은 커밋을 서로 다른 두 환경(배포에 쓰는 리눅스 서버 환경과 개발에 쓰는 윈도우 로컬 환경)에서 각각 빌드해 그 결과물을 직접 비교했다. 포함된 글의 집합은 완전히 같았지만, 19건 중 13건에서 배열 안의 순서가 서로 달랐다.
왜 이게 문제인가
화면에 보이는 텍스트 순서가 아니라 구조화 데이터 안의 순서라, 사람 눈으로 화면을 봐서는 이 문제를 절대 알아챌 수 없다. 하지만 구조화 데이터도 빌드가 만들어 내는 산출물의 일부이고, 같은 소스 코드라면 어떤 환경에서 빌드하든 같은 결과가 나와야 한다는 원칙에 어긋나는 상태였다.
어떻게 고쳤나
발행일 최신순으로 정렬하되, 발행일이 완전히 같은 경우에만 slug 문자열 순서로 한 번 더 정렬하는 비교 함수를 만들어 적용했다. 원본 데이터 배열 자체는 건드리지 않고, 화면 표시·RSS·구조화 데이터가 공유하는 배열의 복사본에만 이 정렬을 걸어, 다른 곳에서 원본 순서에 의존하고 있을지 모르는 코드에 영향을 주지 않게 했다.
검증은 어떻게 했나
같은 코드로 빌드를 두 번 연속 실행해 산출물 전체의 바이트가 완전히 같은지 비교했고, 수정 전과 비교했을 때 달라진 파일이 목록 페이지 하나뿐이며 그 안에서도 글 목록 순서 외에는 아무것도 바뀌지 않았는지 확인했다. 테스트 데이터에도 실제 발행일 분포와 같은 동점 상황을 반영해, 날짜가 겹치는 그룹 사이에 단독 날짜가 끼어 있는 경우까지 검증했다.
이 사건에서 얻은 교훈
정렬 기준이 없는 배열은 “우연히 일관된 순서”로 보일 수 있지만, 실행 환경이 바뀌는 순간 그 우연은 깨진다. 화면에 보이지 않는 데이터라고 해서 결정성 검증에서 제외할 이유는 없다 — 빌드가 만들어 내는 모든 산출물은 같은 입력에 항상 같은 결과를 내야 한다.